home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UInspector.inc1.p < prev    next >
Encoding:
Text File  |  1991-05-01  |  69.2 KB  |  2,621 lines  |  [TEXT/MPS ]

  1. {$P}
  2. {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]}
  3. {UInspector.inc1.p}
  4. {Copyright © 1987-1990 by Apple Computer, Inc.    All rights reserved.}
  5.  
  6. USES
  7.     {
  8.     • List units defining any constants, types or classes that are required for your implementation
  9.     section (e.g. Packages or Errors)
  10.     • Also list units defining the classes that you declared EXTERNAL in the interface section
  11.     or wish to use in the implementation section.
  12.     • Also list the units required by the interfaces of the above units.
  13.     }
  14.      AppleEvents, UEvent, UCommand, UEvtHandler, UList, Editions, Dialogs, UApplication, UDocument,
  15.      Balloons, UViewServer, UAdorners, UView,  UWindow, UScroller, UFailure, UMacAppUniversal, UMacAppUtilities,
  16.      Menus, UMenuMgr, UPatch, UMacAppGlobals, Resources, ToolUtils, Packages, Errors, UGeometry, UDebug, Fonts;
  17.  
  18. {$IFC NOT qDebugTheDebugger}
  19. {$W+}
  20. {$R-}
  21. {$Init-}
  22. {$OV-}
  23. {$ENDC}
  24. {$IFC qNames}
  25. {$D+}
  26. {$ENDC}
  27.  
  28.         CONST
  29.             kInspectorWindowType = 900;
  30.             bInternalString     = - 500;                { used to id strings used internal to
  31.                                                          inspector }
  32.  
  33. TYPE
  34.             TInspectWindow        = OBJECT; FORWARD;
  35.             TObjListView        = OBJECT; FORWARD;
  36.             TObjectView         = OBJECT; FORWARD;
  37.             TClassListView        = OBJECT; FORWARD;
  38.  
  39.             TClassesByID        = OBJECT (TSortedList)
  40.  
  41.                 PROCEDURE TClassesByID.IClassesByID;
  42.  
  43.                 FUNCTION TClassesByID.Compare(item1, item2: TObject): INTEGER; OVERRIDE;
  44.  
  45.                 PROCEDURE TClassesByID.Fields(obj: TObject); OVERRIDE;
  46.  
  47.                 END;
  48.  
  49.             TClassesByName        = OBJECT (TSortedList)
  50.  
  51.                 PROCEDURE TClassesByName.IClassesByName;
  52.  
  53.                 FUNCTION TClassesByName.Compare(item1, item2: TObject): INTEGER; OVERRIDE;
  54.  
  55.                 PROCEDURE TClassesByName.Fields(obj: TObject); OVERRIDE;
  56.  
  57.                 END;
  58.  
  59.             TInspector            = OBJECT (TDocument)
  60.  
  61.                 fClassesByID:        TClassesByID;
  62.                 fClassesByName:     TClassesByName;
  63.                 fWindowCount:        INTEGER;
  64.                 fStaggerCount:        INTEGER;
  65.  
  66.                 PROCEDURE TInspector.Initialize; OVERRIDE;
  67.                 { Puts a newly created TInspector into a known state. Subclasses should
  68.                 override it and call INHERITED. Typically used to put the object into a state where
  69.                 it can be safely FREED. }
  70.  
  71.                 PROCEDURE TInspector.IInspector;
  72.  
  73.                 PROCEDURE TInspector.Free; OVERRIDE;
  74.  
  75.                 FUNCTION TInspector.MakeWindow: TInspectWindow;
  76.  
  77.                 FUNCTION TInspector.AddObjectList(classId: ObjClassID): TSortedList;
  78.  
  79.                 FUNCTION TInspector.GetObjectList(classId: ObjClassID): TSortedList;
  80.  
  81.                 PROCEDURE TInspector.AddObject(theObject: TObject);
  82.  
  83.                 PROCEDURE TInspector.RemoveObject(theObject: TObject);
  84.  
  85.                 PROCEDURE TInspector.DoSetupMenus; OVERRIDE;
  86.  
  87.                 PROCEDURE TInspector.Fields(obj: TObject); OVERRIDE;
  88.  
  89.                 END;
  90.  
  91.             TInspectWindow        = OBJECT (TWindow)
  92.  
  93.                 fClassListView:     TClassListView;
  94.                 fObjListView:        TObjListView;
  95.                 fObjectView:        TObjectView;
  96.  
  97.                 PROCEDURE TInspectWindow.Initialize; OVERRIDE;
  98.                 { Puts a newly created TInspectWindow into a known state. Subclasses should
  99.                 override it and call INHERITED. Typically used to put the object into a state where
  100.                 it can be safely FREED. }
  101.  
  102.                 PROCEDURE TInspectWindow.IRes(itsDocument: TDocument;
  103.                                               itsSuperView: TView;
  104.                                               VAR itsParams: Ptr); OVERRIDE;
  105.                 PROCEDURE TInspectWindow.IInspectWindow;
  106.  
  107.                 PROCEDURE TInspectWindow.Draw(area: VRect); OVERRIDE;
  108.  
  109.                 PROCEDURE TInspectWindow.CloseByUser; OVERRIDE;
  110.  
  111.                 PROCEDURE TInspectWindow.InsertClass(itemNo: INTEGER);
  112.  
  113.                 PROCEDURE TInspectWindow.Resize(newSize: VPoint;
  114.                                              invalidate: BOOLEAN); OVERRIDE;
  115.  
  116.                 PROCEDURE TInspectWindow.SetNumberOfClasses(noOfClasses: INTEGER);
  117.  
  118.                 PROCEDURE TInspectWindow.SetTitleForDoc(newDocTitle: Str255); OVERRIDE;
  119.  
  120.                 PROCEDURE TInspectWindow.SelectObject(theObject: TObject;
  121.                                                       theType: INTEGER);
  122.  
  123.                 PROCEDURE TInspectWindow.Fields(obj: TObject); OVERRIDE;
  124.  
  125.                 END;
  126.  
  127.             TListView            = OBJECT (TView)
  128.  
  129.                 fCurrentSelection:    INTEGER;            { index of the current selection, if any,
  130.                                                          otherwise 0 }
  131.                 fNumberOfItems:     INTEGER;            { number of items currently in the list }
  132.                 fTextStyle:         TextStyle;            { font characteristics }
  133.                 fItemHeight:        INTEGER;            { height of each item including leading }
  134.                 fLineAscent:        INTEGER;            { position of baseline relative to top of
  135.                                                          line }
  136.  
  137.                 PROCEDURE TListView.Initialize; OVERRIDE;
  138.  
  139.                 PROCEDURE TListView.IRes(itsDocument: TDocument;
  140.                                          itsSuperView: TView;
  141.                                          VAR itsParams: Ptr); OVERRIDE;
  142.                 PROCEDURE TListView.IListView(itsDocument: TDocument;
  143.                                               itsSuperView: TView;
  144.                                               itsLocation: VPoint;
  145.                                               itsSize: VPoint;
  146.                                               itsTextStyle: TextStyle;
  147.                                               itsNumberOfItems: INTEGER;
  148.                                               itsHSizeDet: SizeDeterminer);
  149.  
  150.                 PROCEDURE TListView.CalcMinSize(VAR minSize: VPoint); OVERRIDE;
  151.  
  152.                 PROCEDURE TListView.ChangeSelection(index: INTEGER;
  153.                                                     highlight: BOOLEAN);
  154.  
  155.                 PROCEDURE TListView.DoHighlightSelection(fromHL, toHL: HLState); OVERRIDE;
  156.  
  157.                 PROCEDURE TListView.DoMouseCommand(VAR theMouse: VPoint;
  158.                                                    event: TToolboxEvent;
  159.                                                    hysteresis: Point); OVERRIDE;
  160.  
  161.                 PROCEDURE TListView.Draw(area: VRect); OVERRIDE;
  162.  
  163.                 PROCEDURE TListView.DrawItem(itemNumber: INTEGER;
  164.                                              basePoint: VPoint);
  165.  
  166.                 PROCEDURE TListView.Fields(obj: TObject); OVERRIDE;
  167.  
  168.                 PROCEDURE TListView.InsertItem(itemNo: INTEGER);
  169.  
  170.                 PROCEDURE TListView.DeleteItem(itemNo: INTEGER);
  171.  
  172.                 PROCEDURE TListView.ItemToVRect(index: INTEGER;
  173.                                                 VAR itemRect: VRect);
  174.  
  175.                 PROCEDURE TListView.RevealItem(itemNumber: INTEGER);
  176.  
  177.                 PROCEDURE TListView.SelectItem(itemNumber: INTEGER);
  178.  
  179.                 PROCEDURE TListView.SetStyle(itsTextStyle: TextStyle);
  180.  
  181.                 PROCEDURE TListView.SetNumberOfItems(numberOfItems: INTEGER);
  182.  
  183.                 PROCEDURE TListView.SetPen;
  184.  
  185.                 FUNCTION TListView.VPointToItem(thePoint: VPoint): INTEGER;
  186.  
  187.                 END;
  188.  
  189.             TClassListView        = OBJECT (TListView)    {Upper-left view}
  190.  
  191.                 fInspectWindow:     TInspectWindow;
  192.  
  193.                 PROCEDURE TClassListView.Initialize; OVERRIDE;
  194.  
  195.                 PROCEDURE TClassListView.IRes(itsDocument: TDocument;
  196.                                               itsSuperView: TView;
  197.                                               VAR itsParams: Ptr); OVERRIDE;
  198.  
  199.                 PROCEDURE TClassListView.IClassListView(itsWindow: TInspectWindow;
  200.                                                         itsLocation: VPoint;
  201.                                                         itsSize: VPoint);
  202.  
  203.                 PROCEDURE TClassListView.DrawItem(itemNumber: INTEGER;
  204.                                                   basePoint: VPoint); OVERRIDE;
  205.  
  206.                 PROCEDURE TClassListView.SelectItem(itemNumber: INTEGER); OVERRIDE;
  207.  
  208.                 PROCEDURE TClassListView.Fields(obj: TObject); OVERRIDE;
  209.  
  210.                 END;
  211.  
  212.             TObjListView        = OBJECT (TListView)    {Upper-right view}
  213.  
  214.                 fInspectWindow:     TInspectWindow;
  215.                 fObjectList:        TSortedList;
  216.  
  217.                 PROCEDURE TObjListView.Initialize; OVERRIDE;
  218.  
  219.                 PROCEDURE TObjListView.IRes(itsDocument: TDocument;
  220.                                             itsSuperView: TView;
  221.                                             VAR itsParams: Ptr); OVERRIDE;
  222.  
  223.                 PROCEDURE TObjListView.IObjListView(itsWindow: TInspectWindow;
  224.                                                     itsLocation: VPoint;
  225.                                                     itsSize: VPoint);
  226.  
  227.                 PROCEDURE TObjListView.InstallObjectList(theObjectList: TSortedList);
  228.  
  229.                 PROCEDURE TObjListView.DrawItem(itemNumber: INTEGER;
  230.                                                 basePoint: VPoint); OVERRIDE;
  231.  
  232.                 PROCEDURE TObjListView.SelectItem(itemNumber: INTEGER); OVERRIDE;
  233.  
  234.                 PROCEDURE TObjListView.Fields(obj: TObject); OVERRIDE;
  235.  
  236.                 END;
  237.  
  238.             TObjectView         = OBJECT (TListView)    {bottom view}
  239.  
  240.                 fInspectWindow:     TInspectWindow;
  241.                 fObject:            TObject;
  242.                 fType:                INTEGER;
  243.                 fLockState:         BOOLEAN;
  244.                 fFieldsStaticLink:    Ptr;
  245.                 fFieldsProc:        ProcPtr;
  246.  
  247.                 PROCEDURE TObjectView.Initialize; OVERRIDE;
  248.  
  249.                 PROCEDURE TObjectView.IRes(itsDocument: TDocument;
  250.                                            itsSuperView: TView;
  251.                                            VAR itsParams: Ptr); OVERRIDE;
  252.  
  253.                 PROCEDURE TObjectView.IObjectView(itsWindow: TInspectWindow;
  254.                                                   itsLocation: VPoint;
  255.                                                   itsSize: VPoint);
  256.  
  257.                 PROCEDURE TObjectView.InspectControlHandle(PROCEDURE
  258.                                                            InspectField(fieldName: StringPtr;
  259.                                                                         fieldAddr: Ptr;
  260.                                                                         fieldType: INTEGER));
  261.  
  262.                 PROCEDURE TObjectView.InspectGrafPtr(PROCEDURE
  263.                                                      InspectField(fieldName: StringPtr;
  264.                                                                   fieldAddr: Ptr;
  265.                                                                   fieldType: INTEGER));
  266.  
  267.                 PROCEDURE TObjectView.InspectRgnHandle(PROCEDURE
  268.                                                        InspectField(fieldName: StringPtr;
  269.                                                                     fieldAddr: Ptr;
  270.                                                                     fieldType: INTEGER));
  271.  
  272.                 PROCEDURE TObjectView.InspectTEHandle(PROCEDURE
  273.                                                       InspectField(fieldName: StringPtr;
  274.                                                                    fieldAddr: Ptr;
  275.                                                                    fieldType: INTEGER));
  276.  
  277.                 PROCEDURE TObjectView.InspectWindowPtr(PROCEDURE
  278.                                                        InspectField(fieldName: StringPtr;
  279.                                                                     fieldAddr: Ptr;
  280.                                                                     fieldType: INTEGER));
  281.  
  282.                 PROCEDURE TObjectView.InspectHandle(PROCEDURE
  283.                                                     InspectField(fieldName: StringPtr;
  284.                                                                  fieldAddr: Ptr;
  285.                                                                  fieldType: INTEGER));
  286.  
  287.                 PROCEDURE TObjectView.LockObject;
  288.  
  289.                 PROCEDURE TObjectView.UnlockObject;
  290.  
  291.                 PROCEDURE TObjectView.ChangeSelection(index: INTEGER;
  292.                                                       highlight: BOOLEAN); OVERRIDE;
  293.  
  294.                 PROCEDURE TObjectView.SelectField(index: INTEGER;
  295.                                                   inspectWindow: TInspectWindow);
  296.  
  297.                 PROCEDURE TObjectView.DoMouseCommand(VAR theMouse: VPoint;
  298.                                                      event: TToolboxEvent;
  299.                                                      hysteresis: Point); OVERRIDE;
  300.  
  301.                 PROCEDURE TObjectView.Draw(area: VRect); OVERRIDE;
  302.  
  303.                 PROCEDURE TObjectView.DrawItem(itemNumber: INTEGER;
  304.                                                basePoint: VPoint); OVERRIDE;
  305.  
  306.                 PROCEDURE TObjectView.SuperViewChangedSize(delta: VPoint;
  307.                                                            invalidate: BOOLEAN); OVERRIDE;
  308.  
  309.                 PROCEDURE TObjectView.Resize(newSize: VPoint;
  310.                                              invalidate: BOOLEAN); OVERRIDE;
  311.  
  312.                 PROCEDURE TObjectView.FirstFieldThat(FUNCTION
  313.                                                      TestField(fieldName: StringPtr;
  314.                                                                fieldAddr: Ptr;
  315.                                                                fieldType: INTEGER): BOOLEAN);
  316.  
  317.                 PROCEDURE TObjectView.InstallObject(theObject: TObject;
  318.                                                     theObjectType: INTEGER);
  319.  
  320.                 PROCEDURE TObjectView.Fields(obj: TObject); OVERRIDE;
  321.                 PROCEDURE TObjectView.DoToField(fieldName: StringPtr;
  322.                                                 fieldAddr: Ptr;
  323.                                                 fieldType: INTEGER); OVERRIDE;
  324.  
  325.                 END;
  326.  
  327.  
  328.  
  329. VAR
  330. {$Push} {$Z+}                                            { Make the root of the inspector visible to
  331.                                                          selected friends }
  332.     pInspector:         TInspector;
  333. {$Pop}
  334.     pInspectorStyle:    TextStyle;
  335.     pSavedFocus:        FocusRec;
  336.     pAddNewObjectsToInspector: BOOLEAN;
  337.  
  338. {$IFC qTrace} {$D+} {$ENDC}                             { Turn off tracing for all Inspector code in
  339.                                                          this file }
  340. {$S MAInspector}                                        { Everything goes in here }
  341.  
  342.     {---------------------------------------------------------------------------}
  343.  
  344. {$Push}
  345. {$IFC qTrace}
  346. {$IFC qDebugTheDebugger}
  347. {$D++}
  348. {$ENDC}
  349. {$ENDC}
  350.  
  351. PROCEDURE AddObjectToInspector(theObject: TObject);
  352.  {This is called from %_OBNEW when an object is created, and from
  353.   TObject.ShallowClone when cloning an object.}
  354.  
  355.     BEGIN
  356.     IF pAddNewObjectsToInspector & (pInspector <> NIL) & (theObject <> NIL) THEN
  357.         pInspector.AddObject(theObject);
  358.     END;
  359. {$Pop}
  360.  
  361. {--------------------------------------------------------------------------------------------------}
  362.  
  363. FUNCTION AddNewObjectsToInspector(add: BOOLEAN): BOOLEAN;
  364.  
  365.     BEGIN
  366.     AddNewObjectsToInspector := pAddNewObjectsToInspector;
  367.     pAddNewObjectsToInspector := add;
  368.     END;
  369.  
  370. {---------------------------------------------------------------------------}
  371.  
  372. PROCEDURE InitUInspector;
  373.  
  374.     BEGIN
  375.     IF qInspector THEN
  376.         pAddNewObjectsToInspector := false;
  377.  
  378.     pInspector := NIL;
  379.     SetTextStyle(pInspectorStyle, applFont, [], 9, gRGBBlack);
  380.     pSavedFocus.itsViewPortInfo.clip := MakeNewRgn;
  381.  
  382.     IF qTemplateViews THEN
  383.         BEGIN
  384.         { Make sure linker doesn't dead strip these }
  385.         IF gDeadStripSuppression THEN
  386.             BEGIN
  387.             IF Member(TObject(NIL), TInspectWindow) THEN;
  388.             IF Member(TObject(NIL), TClassListView) THEN;
  389.             IF Member(TObject(NIL), TObjListView) THEN;
  390.             IF Member(TObject(NIL), TObjectView) THEN;
  391.             END;
  392.         END;
  393.  
  394.     IF qInspector THEN
  395.         pAddNewObjectsToInspector := TRUE;
  396.  
  397.     END;
  398.  
  399. {---------------------------------------------------------------------------}
  400.  
  401. PROCEDURE MakeInspector;
  402.  
  403.     VAR
  404.         anInspector:        TInspector;
  405.         wasAddNewObjectsToInspector: BOOLEAN;
  406.         wasTrcEnable:        BOOLEAN;
  407.  
  408.     BEGIN
  409. {$IFC NOT qDebugTheDebugger}
  410. {$IFC qDebug}
  411.     wasTrcEnable := TrcEnable(False);
  412. {$EndC}
  413.     wasAddNewObjectsToInspector := AddNewObjectsToInspector(False);
  414. {$ENDC}
  415.  
  416.     { Allocate and initialize the document}
  417.     New(anInspector);
  418.     anInspector.IInspector;
  419.  
  420. {$IFC NOT qDebugTheDebugger}
  421.     IF AddNewObjectsToInspector(wasAddNewObjectsToInspector) THEN;
  422. {$IFC qDebug}
  423.     IF TrcEnable(wasTrcEnable) THEN;
  424. {$EndC}
  425. {$ENDC}
  426.     END;
  427.  
  428. {---------------------------------------------------------------------------}
  429.  
  430. PROCEDURE MakeInspectorWindow;
  431.  
  432.     VAR
  433.         wasAddNewObjectsToInspector: BOOLEAN;
  434.         wasTrcEnable:        BOOLEAN;
  435.         anInspectWindow:    TInspectWindow;
  436.  
  437.     BEGIN
  438. {$IFC NOT qDebugTheDebugger}
  439. {$IFC qDebug}
  440.     wasTrcEnable := TrcEnable(False);
  441. {$EndC}
  442.     wasAddNewObjectsToInspector := AddNewObjectsToInspector(False);
  443. {$ENDC}
  444.  
  445.     IF pInspector <> NIL THEN
  446.         BEGIN
  447.         anInspectWindow := pInspector.MakeWindow;
  448.         anInspectWindow.Open;
  449.         END;
  450.  
  451. {$IFC NOT qDebugTheDebugger}
  452.     IF AddNewObjectsToInspector(wasAddNewObjectsToInspector) THEN;
  453. {$IFC qDebug}
  454.     IF TrcEnable(wasTrcEnable) THEN;
  455. {$EndC}
  456. {$ENDC}
  457.     END;
  458.  
  459. {---------------------------------------------------------------------------}
  460.  
  461. {$Push}
  462. {$IFC qTrace}
  463. {$IFC qDebugTheDebugger}
  464. {$D++}
  465. {$ENDC}
  466. {$ENDC}
  467.  
  468. PROCEDURE RemoveObjectFromInspector(theObject: TObject);
  469. {Called from TObject.Free.}
  470.  
  471.     VAR
  472.         wasAddNewObjectsToInspector: BOOLEAN;
  473.         wasTrcEnable:        BOOLEAN;
  474.  
  475.     BEGIN
  476. {$IFC NOT qDebugTheDebugger}
  477. {$IFC qDebug}
  478.     wasTrcEnable := TrcEnable(False);
  479. {$EndC}
  480.     wasAddNewObjectsToInspector := AddNewObjectsToInspector(False);
  481. {$ENDC}
  482.     IF NOT gApplication.fAppDone THEN
  483.         IF (pInspector <> NIL) & (theObject <> NIL) THEN
  484.             pInspector.RemoveObject(theObject);
  485. {$IFC NOT qDebugTheDebugger}
  486.     IF AddNewObjectsToInspector(wasAddNewObjectsToInspector) THEN;
  487. {$IFC qDebug}
  488.     IF TrcEnable(wasTrcEnable) THEN;
  489. {$EndC}
  490. {$ENDC}
  491.     END;
  492. {$Pop}
  493.  
  494. {---------------------------------------------------------------------------}
  495.  
  496. PROCEDURE TClassesByID.IClassesByID;
  497.  
  498.     BEGIN
  499.     ISortedList;
  500.     END;
  501.  
  502. {---------------------------------------------------------------------------}
  503.  
  504. FUNCTION TClassesByID.Compare(item1, item2: TObject): INTEGER; OVERRIDE;
  505.  
  506.     BEGIN
  507.     IF TSortedList(item1).fObjClassId < TSortedList(item2).fObjClassId THEN
  508.         Compare := kItem1LessThanItem2
  509.     ELSE IF TSortedList(item1).fObjClassId > TSortedList(item2).fObjClassId THEN
  510.         Compare := kItem1GreaterThanItem2
  511.     ELSE
  512.         Compare := kItem1EqualItem2;
  513.     END;
  514.  
  515. {---------------------------------------------------------------------------}
  516.  
  517. PROCEDURE TClassesByID.Fields(obj: TObject); OVERRIDE;
  518.  
  519.     BEGIN
  520.     WITH obj DO
  521.         BEGIN
  522.         DoToField(AtStr('TClassesByID'), NIL, bClass);
  523.         END;
  524.     INHERITED Fields(obj);
  525.     END;
  526.  
  527. {---------------------------------------------------------------------------}
  528.  
  529. PROCEDURE TClassesByName.IClassesByName;
  530.  
  531.     BEGIN
  532.     ISortedList;
  533.     END;
  534.  
  535. {---------------------------------------------------------------------------}
  536.  
  537. FUNCTION TClassesByName.Compare(item1, item2: TObject): INTEGER; OVERRIDE;
  538.  
  539.     VAR
  540.         string1, string2:    MAName;
  541.  
  542.     BEGIN
  543.     GetClassNameFromID(TSortedList(item1).fObjClassId, string1);
  544.     GetClassNameFromID(TSortedList(item2).fObjClassId, string2);
  545.     IF string1 < string2 THEN
  546.         Compare := kItem1LessThanItem2
  547.     ELSE IF string1 > string2 THEN
  548.         Compare := kItem1GreaterThanItem2
  549.     ELSE
  550.         Compare := kItem1EqualItem2;
  551.     END;
  552.  
  553. {---------------------------------------------------------------------------}
  554.  
  555. PROCEDURE TClassesByName.Fields(obj: TObject); OVERRIDE;
  556.  
  557.     BEGIN
  558.     WITH obj DO
  559.         BEGIN
  560.         DoToField(AtStr('TClassesByName'), NIL, bClass);
  561.         END;
  562.     INHERITED Fields(obj);
  563.     END;
  564.  
  565. {--------------------------------------------------------------------------------------------------}
  566.  
  567. PROCEDURE TInspector.Initialize; OVERRIDE;
  568.  
  569.     BEGIN
  570.     INHERITED Initialize;
  571.     fClassesByID := NIL;
  572.     fClassesByName := NIL;
  573.     fStaggerCount := 0;
  574.     fWindowCount := 0;
  575.     END;
  576.  
  577. {---------------------------------------------------------------------------}
  578.  
  579. PROCEDURE TInspector.IInspector;
  580.  
  581.     VAR
  582.         aClassesByName:     TClassesByName;
  583.         aClassesById:        TClassesByID;
  584.  
  585.     BEGIN
  586.     IDocument;
  587.     SetTitle('Inspector');
  588.  
  589.     New(aClassesByName);
  590.     aClassesByName.IClassesByName;
  591.     aClassesByName.SetEltType('TSortedList');
  592.     fClassesByName := aClassesByName;
  593.  
  594.     New(aClassesById);
  595.     aClassesById.IClassesByID;
  596.     aClassesById.SetEltType('TSortedList');
  597.     fClassesByID := aClassesById;
  598.  
  599.     pInspector := SELF;
  600.     END;
  601.  
  602. {---------------------------------------------------------------------------}
  603.  
  604. PROCEDURE TInspector.Free; OVERRIDE;
  605.  
  606.     BEGIN
  607.     fClassesByID := TClassesByID(FreeListIfObject(fClassesByID));
  608.  
  609.     fClassesByName := TClassesByName(FreeIfObject(fClassesByName));
  610.  
  611.     pInspector := NIL;
  612.  
  613.     INHERITED Free;
  614.     END;
  615.  
  616. {---------------------------------------------------------------------------}
  617.  
  618. PROCEDURE TInspector.Fields(obj: TObject); OVERRIDE;
  619.  
  620.     BEGIN
  621.     WITH obj DO
  622.         BEGIN
  623.         DoToField(AtStr('TInspector'), NIL, bClass);
  624.         DoToField(AtStr('fClassesByID'), @fClassesByID, bObject);
  625.         DoToField(AtStr('fClassesByName'), @fClassesByName, bObject);
  626.         DoToField(AtStr('fWindowCount'), @fWindowCount, bInteger);
  627.         DoToField(AtStr('fStaggerCount'), @fStaggerCount, bInteger);
  628.         END;
  629.     INHERITED Fields(obj);
  630.     END;
  631.  
  632. {---------------------------------------------------------------------------}
  633.  
  634. FUNCTION TInspector.MakeWindow: TInspectWindow;
  635.  
  636.     VAR
  637.         anInspectWindow:    TInspectWindow;
  638.         staggerCount:        INTEGER;
  639.         screenRect:         Rect;
  640.         aVPt:                VPoint;
  641.  
  642.     BEGIN
  643.     fWindowCount := fWindowCount + 1;
  644.  
  645.     IF qTemplateViews THEN
  646.         BEGIN
  647.         anInspectWindow := TInspectWindow(gViewServer.NewTemplateWindow(kInspectorWindowType, SELF));
  648.  
  649.         WITH anInspectWindow DO
  650.             BEGIN
  651.  
  652.             fClassListView := TClassListView(FindSubView('IVW1'));
  653.             fObjListView := TObjListView(FindSubView('IVW2'));
  654.             fObjectView := TObjectView(FindSubView('IVW3'));
  655.  
  656.             fClassListView.fInspectWindow := anInspectWindow;
  657.             fObjListView.fInspectWindow := anInspectWindow;
  658.             fObjectView.fInspectWindow := anInspectWindow;
  659.  
  660.             { Use GetMaxIntersectedDevice to Locate our window. }
  661.             IF GetMaxIntersectedDevice(screenRect) = NIL THEN;
  662.             WITH screenRect DO
  663.                 BEGIN
  664.                 SetVPt(aVPt, right - fWMgrWindow^.portRect.right, top + fContRgnInset.v);
  665.                 Locate(aVPt, kDontInvalidate);
  666.  
  667.                 {Adapt height of window to height of screen}
  668.                 SetVPt(aVPt, fWMgrWindow^.portRect.right, Max(252, bottom - 192));
  669.                 IF bottom > 342 THEN
  670.                     Resize(aVPt, kDontInvalidate);
  671.  
  672.                 END;
  673.             END;
  674.         END
  675.  
  676.     ELSE
  677.         BEGIN
  678.         New(anInspectWindow);
  679.         anInspectWindow.IInspectWindow;
  680.         anInspectWindow.ForceOnScreen;
  681.         END;
  682.  
  683.     WITH anInspectWindow DO
  684.         BEGIN
  685.         staggerCount := fStaggerCount;
  686.         SimpleStagger( - kStdStaggerAmount, kStdStaggerAmount, staggerCount);
  687.         fStaggerCount := staggerCount;
  688.  
  689.         SetNumberOfClasses(fClassesByID.GetSize);
  690.  
  691.         { Installs print handler if client app is using printing }
  692.         InstallIfPrintHandler(gPrintHandler, fObjectView);
  693.  
  694.         END;
  695.  
  696.     MakeWindow := anInspectWindow;
  697.     END;
  698.  
  699. {---------------------------------------------------------------------------}
  700.  
  701. PROCEDURE TInspector.AddObject(theObject: TObject);
  702.  
  703.     VAR
  704.         classId:            ObjClassID;
  705.         theObjectList:        TSortedList;
  706.  
  707.     PROCEDURE ResetObjListView(aWindow: TInspectWindow);
  708.  
  709.         VAR
  710.             objListView:        TObjListView;
  711.  
  712.         BEGIN
  713.         objListView := aWindow.fObjListView;
  714.         IF objListView.fObjectList = theObjectList THEN
  715.             objListView.InsertItem(objListView.fNumberOfItems + 1);
  716.         END;
  717.  
  718.     BEGIN
  719.     GetFocus(pSavedFocus);
  720.     gPrinting := False;
  721.     gDrawingPictScrap := False;
  722.     gDrawingPictScrapView := NIL;
  723.     classId := GetClassID(theObject);
  724.     theObjectList := GetObjectList(classId);
  725.     IF theObjectList = NIL THEN
  726.         theObjectList := AddObjectList(classId);
  727.     theObjectList.Insert(theObject);
  728.     IF (fWindowList <> NIL) & (fWindowList.GetSize > 0) THEN
  729.         BEGIN
  730.         ForAllWindowsDo(ResetObjListView);
  731.         END;
  732.     SetFocus(pSavedFocus);
  733.     END;
  734.  
  735. {---------------------------------------------------------------------------}
  736.  
  737. FUNCTION TInspector.AddObjectList(classId: ObjClassID): TSortedList;
  738.  
  739.     VAR
  740.         anObjectList:        TSortedList;
  741.         classListItemNo:    INTEGER;
  742.         oldAddNewObjectsToInspector: BOOLEAN;
  743.  
  744.     PROCEDURE ResetClassListView(aWindow: TInspectWindow);
  745.  
  746.         BEGIN
  747.         aWindow.InsertClass(classListItemNo);
  748.         END;
  749.  
  750.     BEGIN
  751.     oldAddNewObjectsToInspector := AddNewObjectsToInspector(FALSE);
  752.     New(anObjectList);
  753.     IF AddNewObjectsToInspector(oldAddNewObjectsToInspector) THEN;
  754.  
  755.     anObjectList.ISortedList;
  756.     anObjectList.SetEltTypeID(classId);
  757.  
  758.     fClassesByID.Insert(anObjectList);
  759.     fClassesByName.Insert(anObjectList);
  760.     classListItemNo := fClassesByName.GetIdentityItemNo(anObjectList);
  761.     ForAllWindowsDo(ResetClassListView);
  762.     AddObjectList := anObjectList;
  763.     END;
  764.  
  765. {---------------------------------------------------------------------------}
  766.  
  767. PROCEDURE TInspector.DoSetupMenus; OVERRIDE;
  768.  
  769.     BEGIN
  770.     INHERITED DoSetupMenus;
  771.  
  772.     Enable(cSaveAs, False);
  773.     Enable(cSaveCopy, False);
  774.     END;
  775.  
  776. {---------------------------------------------------------------------------}
  777.  
  778. FUNCTION TInspector.GetObjectList(classId: ObjClassID): TSortedList;
  779.  
  780.     FUNCTION TestClass(anObjectList: TSortedList): INTEGER;
  781.  
  782.         BEGIN
  783.         IF classId < anObjectList.fObjClassId THEN
  784.             TestClass := kItemGreaterThanCriteria
  785.         ELSE IF classId > anObjectList.fObjClassId THEN
  786.             TestClass := kItemLessThanCriteria
  787.         ELSE
  788.             TestClass := kItemEqualCriteria;
  789.         END;
  790.  
  791.     BEGIN
  792.     GetObjectList := TSortedList(fClassesByID.Search(TestClass));
  793.     END;
  794.  
  795. {---------------------------------------------------------------------------}
  796.  
  797. PROCEDURE TInspector.RemoveObject(theObject: TObject);
  798.  
  799.     VAR
  800.         theObjectList:        TSortedList;
  801.         index:                INTEGER;
  802.  
  803.     PROCEDURE CheckWindow(theInspectWindow: TInspectWindow);
  804.  
  805.         BEGIN
  806.         IF theInspectWindow.fObjectView.fObject = theObject THEN
  807.             theInspectWindow.fObjectView.InstallObject(NIL, 0);
  808.         IF theInspectWindow.fObjListView.fObjectList = theObjectList THEN
  809.             theInspectWindow.fObjListView.DeleteItem(index);
  810.         END;
  811.  
  812.     BEGIN
  813.     IF (fClassesByID <> NIL) THEN
  814.         BEGIN
  815.         GetFocus(pSavedFocus);
  816.         gPrinting := False;
  817.         gDrawingPictScrap := False;
  818.         gDrawingPictScrapView := NIL;
  819.         theObjectList := GetObjectList(ObjClassIdHandle(theObject)^^);
  820.         IF theObjectList <> NIL THEN
  821.             BEGIN
  822.             index := theObjectList.GetEqualItemNo(theObject);
  823.             theObjectList.Delete(theObject);
  824.             IF (fWindowList <> NIL) & (fWindowList.GetSize > 0) THEN
  825.                 BEGIN
  826.                 ForAllWindowsDo(CheckWindow);
  827.                 END;
  828.             END;
  829.         SetFocus(pSavedFocus);
  830.         END;
  831.     END;
  832.  
  833. {---------------------------------------------------------------------------}
  834.  
  835. PROCEDURE TInspectWindow.IRes(itsDocument: TDocument;
  836.                               itsSuperView: TView;
  837.                               VAR itsParams: Ptr); OVERRIDE;
  838.  
  839.     BEGIN
  840.     INHERITED IRes(itsDocument, itsSuperView, itsParams);
  841.  
  842. {$Push} {$H-}
  843.     SetPt(fResizeLimits.topLeft, 151, 142);
  844. {$Pop}
  845.     END;
  846.  
  847. {---------------------------------------------------------------------------}
  848.  
  849. PROCEDURE TInspectWindow.Initialize; OVERRIDE;
  850.  
  851.     BEGIN
  852.     INHERITED Initialize;
  853.     fClassListView := NIL;
  854.     fObjListView := NIL;
  855.     fObjectView := NIL;
  856.     END;
  857.  
  858. PROCEDURE TInspectWindow.IInspectWindow;
  859.  
  860.     VAR
  861.         aWMgrWindow:        WindowPtr;
  862.         canResize:            BOOLEAN;
  863.         canClose:            BOOLEAN;
  864.         fi:                 FailInfo;
  865.         aClassListView:     TClassListView;
  866.         anObjListView:        TObjListView;
  867.         anObjectView:        TObjectView;
  868.         aScroller:            TScroller;
  869.         itsLocation:        VPoint;
  870.         itsSize:            VPoint;
  871.         screenRect:         Rect;
  872.         aVPt:                VPoint;
  873.  
  874.     PROCEDURE HandleFailure(error: INTEGER;
  875.                             message: LONGINT);
  876.  
  877.         BEGIN
  878.         {the wmgrWindow is known to exist}
  879.   {Since aWindow didn't get created, the wmgrWindow won't be
  880.    freed unless we do it here.}
  881.  
  882.         aWMgrWindow := FreeIfWMgrWindow(aWMgrWindow, TRUE);
  883.  
  884.         END;
  885.  
  886.     BEGIN
  887.  
  888.     aWMgrWindow := NIL;
  889.     aWMgrWindow := gApplication.GetRsrcWindow(NIL, kInspectorWindowType, canResize, canClose);
  890.     {GetRsrcWindow signals Failure}
  891.  
  892.     CatchFailures(fi, HandleFailure);
  893.     IWindow(pInspector, aWMgrWindow, canResize, canClose, TRUE);
  894. {$Push} {$H-}
  895.     SetPt(fResizeLimits.topLeft, 151, 142);
  896. {$Pop}
  897.  
  898.     fClosesDocument := False;
  899.     fFreeOnClosing := TRUE;
  900.  
  901.     SetVPt(itsLocation, 0, 0);
  902.     SetVPt(itsSize, 65, 12 * 6);
  903.     New(aClassListView);
  904.     aClassListView.IClassListView(SELF, itsLocation, itsSize);
  905.     fClassListView := aClassListView;
  906.  
  907.     SetVPt(itsLocation, 81, 0);
  908.     SetVPt(itsSize, 200 - 81, 12 * 6);
  909.     New(anObjListView);
  910.     anObjListView.IObjListView(SELF, itsLocation, itsSize);
  911.     fObjListView := anObjListView;
  912.  
  913.     SetVPt(itsLocation, 0, 12 * 6 + 1);
  914.     SetVPt(itsSize, 200, fWMgrWindow^.portRect.bottom - itsLocation.v);
  915.     New(anObjectView);
  916.     anObjectView.IObjectView(SELF, itsLocation, itsSize);
  917.     fObjectView := anObjectView;
  918.  
  919.     SetTarget(anObjectView);                            { !!! }
  920.  
  921.     fSize := gZeroVPt;                                    { Make sure window gets resized }
  922.     WITH fWMgrWindow^.portRect DO
  923.         begin
  924.         SetVPt(aVPt, right - left, bottom - top);
  925.         Resize(aVPt, kDontInvalidate);
  926.         end;
  927.  
  928.     { Use GetMaxIntersectedDevice to Locate our window. }
  929.     IF GetMaxIntersectedDevice(screenRect) = NIL THEN;
  930.     WITH screenRect DO
  931.         BEGIN
  932.         SetVPt(aVPt, right - fWMgrWindow^.portRect.right, top + fContRgnInset.v);
  933.         Locate(aVPt, kDontInvalidate);
  934.  
  935.         {Adapt height of window to height of screen}
  936.         SetVPt(aVPt, fWMgrWindow^.portRect.right, Max(252, bottom - 192));
  937.         IF bottom > 342 THEN
  938.             Resize(aVPt, kDontInvalidate);
  939.         END;
  940.  
  941.     Success(fi);
  942.     END;
  943.  
  944. {---------------------------------------------------------------------------}
  945.  
  946. PROCEDURE TInspectWindow.CloseByUser; OVERRIDE;
  947.  
  948.     BEGIN
  949.  {Overridden to prevent closing the Inspector document when the last
  950.   inspector window is closed.}
  951.     Close;
  952.     END;
  953.  
  954. {---------------------------------------------------------------------------}
  955.  
  956. PROCEDURE TInspectWindow.Draw(area: VRect); OVERRIDE;
  957.  
  958.     BEGIN
  959.     INHERITED Draw(area);
  960.  
  961.     {Draw horizontal line separating upper views from lower view}
  962.     PenNormal;
  963.     MoveTo(0, fObjectView.fSuperView.fLocation.v - 1);
  964.     Line(fSize.h, 0);
  965.     END;
  966.  
  967. {---------------------------------------------------------------------------}
  968.  
  969. PROCEDURE TInspectWindow.Fields(obj: TObject); OVERRIDE;
  970.  
  971.     BEGIN
  972.     WITH obj DO
  973.         BEGIN
  974.         DoToField(AtStr('TInspectWindow'), NIL, bClass);
  975.         DoToField(AtStr('fClassListView'), @fClassListView, bObject);
  976.         DoToField(AtStr('fObjListView'), @fObjListView, bObject);
  977.         DoToField(AtStr('fObjectView'), @fObjectView, bObject);
  978.         END;
  979.     INHERITED Fields(obj);
  980.     END;
  981.  
  982. {---------------------------------------------------------------------------}
  983.  
  984. PROCEDURE TInspectWindow.Resize(newSize: VPoint;
  985.                                 invalidate: BOOLEAN); OVERRIDE;
  986.  
  987.     VAR
  988.         aVPt:                VPoint;
  989.  
  990.     BEGIN
  991.     INHERITED Resize(newSize, invalidate);
  992.  
  993.  {Resize the upper-right and bottom view to match the window's
  994.   new size.}
  995.     IF fClassListView <> NIL THEN
  996.         BEGIN
  997.         SetVPt(aVPt, BSR(newSize.h, 1) - kSBarSizeMinus1, fSize.v);
  998.         WITH fClassListView.fSuperView DO
  999.             fClassListView.fSuperView.Resize(aVPt, invalidate);
  1000.         END;
  1001.     IF fObjListView <> NIL THEN
  1002.         BEGIN
  1003.         SetVPt(aVPt, BSR(newSize.h, 1) + 1, 0);
  1004.         fObjListView.fSuperView.Locate(aVPt, invalidate);
  1005.         SetVPt(aVPt, newSize.h - fLocation.h - kSBarSizeMinus1, fSize.v);
  1006.         WITH fObjListView.fSuperView DO
  1007.             fObjListView.fSuperView.Resize(aVPt, invalidate);
  1008.         END;
  1009.     IF fObjectView <> NIL THEN
  1010.         BEGIN
  1011.         SetVPt(aVPt, newSize.h - kSBarSizeMinus1, (newSize.v -
  1012.                                           fObjectView.fSuperView.fLocation.v) - kSBarSizeMinus1);
  1013.         WITH fObjectView.fSuperView DO
  1014.             fObjectView.fSuperView.Resize(aVPt, invalidate);
  1015.         END;
  1016.     END;
  1017.  
  1018. {---------------------------------------------------------------------------}
  1019.  
  1020. PROCEDURE TInspectWindow.InsertClass(itemNo: INTEGER);
  1021.  
  1022.     BEGIN
  1023.     IF fClassListView <> NIL THEN
  1024.         fClassListView.InsertItem(itemNo);
  1025.     END;
  1026.  
  1027. {---------------------------------------------------------------------------}
  1028.  
  1029. PROCEDURE TInspectWindow.SetNumberOfClasses(noOfClasses: INTEGER);
  1030.  
  1031.     BEGIN
  1032.     IF fClassListView <> NIL THEN
  1033.         fClassListView.SetNumberOfItems(noOfClasses);
  1034.     END;
  1035.  
  1036. {---------------------------------------------------------------------------}
  1037.  
  1038. PROCEDURE TInspectWindow.SetTitleForDoc(newDocTitle: Str255); OVERRIDE;
  1039.     VAR
  1040.         aTitle: Str255;
  1041.         aString: Str255;
  1042.     BEGIN
  1043.     aString := 'Inspector ';
  1044.     ConcatNumber(aString, pInspector.fWindowCount,aTitle);
  1045.     
  1046.     SetTitle(aTitle);
  1047.     END;
  1048.  
  1049. {---------------------------------------------------------------------------}
  1050.  
  1051. PROCEDURE TInspectWindow.SelectObject(theObject: TObject;
  1052.                                       theType: INTEGER);
  1053.  
  1054.  {This installs the given object as the selected object of the window,
  1055.   making sure that the class list and object list views are in sync.}
  1056.  
  1057.     VAR
  1058.         objectItemNumber, classItemNumber: INTEGER;
  1059.         classId:            ObjClassID;
  1060.         anObjectList:        TSortedList;
  1061.         anObject:            TObject;
  1062.  
  1063.     FUNCTION TestClass(anObjectList: TSortedList): BOOLEAN;
  1064.  
  1065.         BEGIN
  1066.         classItemNumber := classItemNumber + 1;
  1067.         TestClass := anObjectList.fObjClassId = classId;
  1068.         END;
  1069.  
  1070.     FUNCTION TestObject(anObject: TObject): BOOLEAN;
  1071.  
  1072.         BEGIN
  1073.         objectItemNumber := objectItemNumber + 1;
  1074.         TestObject := anObject = theObject;
  1075.         END;
  1076.  
  1077.     BEGIN
  1078.     IF NOT (ODD(LONGINT(theObject))) THEN                {* check for uninitialized object *}
  1079.         BEGIN
  1080.         IF theType = bObject THEN
  1081.             BEGIN
  1082.             {* get the new class *}
  1083.             classItemNumber := 0;
  1084.             classId := GetClassID(theObject);
  1085.             anObjectList := TSortedList(pInspector.fClassesByName.FirstThat(TestClass));
  1086.             IF anObjectList <> NIL THEN
  1087.                 BEGIN
  1088.                 objectItemNumber := 0;
  1089.                 anObject := anObjectList.FirstThat(TestObject);
  1090.                 IF anObject <> NIL THEN
  1091.                     BEGIN
  1092.                     { turn off the old class and select the new class }
  1093.                     fClassListView.ChangeSelection(classItemNumber, TRUE);
  1094.                     fClassListView.RevealItem(classItemNumber);
  1095.                     { turn off the old item and select the new item }
  1096.                     fObjListView.ChangeSelection(objectItemNumber, TRUE);
  1097.                     END;
  1098.                 END
  1099. {$IFC qDebugTheDebugger}
  1100.             ELSE
  1101.                 BEGIN
  1102.                 ProgramBreak('TInspectWindow.SelectObject: Unable to find class');
  1103.                 END
  1104. {$ENDC}
  1105.             ;
  1106.             END
  1107.  
  1108.         ELSE IF theType <> 0 THEN
  1109.             fObjectView.InstallObject(theObject, theType);
  1110.         END;
  1111.     END;
  1112.  
  1113. { Based on work by Kurt Shmucker Copyright 1986 by Productivity Products International, Inc.
  1114.     Used by permission. }
  1115.  
  1116. {--------------------------------------------------------------------------------------------------}
  1117.  
  1118. PROCEDURE TListView.Initialize; OVERRIDE;
  1119.  
  1120.     BEGIN
  1121.     INHERITED Initialize;
  1122.  
  1123.     fCurrentSelection := 0;
  1124.     fItemHeight := 0;                                    {!!! Better defaults? }
  1125.     fLineAscent := 0;
  1126.     fNumberOfItems := 0;
  1127.     fTextStyle := pInspectorStyle;
  1128.     END;
  1129.  
  1130. {---------------------------------------------------------------------------}
  1131.  
  1132. PROCEDURE TListView.IRes(itsDocument: TDocument;
  1133.                          itsSuperView: TView;
  1134.                          VAR itsParams: Ptr); OVERRIDE;
  1135.  
  1136.     BEGIN
  1137.     INHERITED IRes(itsDocument, itsSuperView, itsParams);
  1138.  
  1139.     SetStyle(pInspectorStyle);
  1140.     END;
  1141.  
  1142. {--------------------------------------------------------------------------------------------------}
  1143.  
  1144. PROCEDURE TListView.IListView(itsDocument: TDocument;
  1145.                               itsSuperView: TView;
  1146.                               itsLocation: VPoint;
  1147.                               itsSize: VPoint;
  1148.                               itsTextStyle: TextStyle;
  1149.                               itsNumberOfItems: INTEGER;
  1150.                               itsHSizeDet: SizeDeterminer);
  1151.  
  1152.     BEGIN
  1153.     IView(itsDocument, itsSuperView, itsLocation, itsSize, itsHSizeDet, sizeVariable);
  1154.     fNumberOfItems := itsNumberOfItems;
  1155.     SetStyle(itsTextStyle);
  1156.  
  1157.     AddAdorner(gSelectionAdorner, kViewAdornPriority, FALSE);                        { wants DoHighlightSelection }
  1158.     END;
  1159.  
  1160. {--------------------------------------------------------------------------------------------------}
  1161.  
  1162. PROCEDURE TListView.CalcMinSize(VAR minSize: VPoint); OVERRIDE;
  1163.  
  1164.     BEGIN
  1165.     INHERITED CalcMinSize(minSize);
  1166.     { Set the amount of room needed for that many items }
  1167.     minSize.v := IntMultiply(fNumberOfItems, fItemHeight);
  1168.  
  1169.     IF fNumberOfItems <> 0 THEN
  1170.         minSize.h := Max(600, fSuperView.fSize.h)
  1171.     ELSE
  1172.         minSize.h := 0;
  1173.     END;
  1174.  
  1175. {--------------------------------------------------------------------------------------------------}
  1176.  
  1177. PROCEDURE TListView.ChangeSelection(index: INTEGER;
  1178.                                     highlight: BOOLEAN);
  1179.  
  1180.     BEGIN
  1181.     IF highlight & IsDrawable THEN
  1182.         BEGIN
  1183.         DoHighlightSelection(fHLDesired, hlOff);
  1184.         fCurrentSelection := index;
  1185.         DoHighlightSelection(hlOff, fHLDesired);
  1186.         END
  1187.     ELSE
  1188.         fCurrentSelection := index;
  1189.     SelectItem(index);
  1190.     END;
  1191.  
  1192. {--------------------------------------------------------------------------------------------------}
  1193.  
  1194. PROCEDURE TListView.DeleteItem(itemNo: INTEGER);
  1195.  
  1196.     VAR
  1197.         topRect, bottomRect: VRect;
  1198.  
  1199.     BEGIN
  1200.     IF fCurrentSelection > 0 THEN
  1201.         IF itemNo < fCurrentSelection THEN
  1202.             fCurrentSelection := fCurrentSelection - 1
  1203.         ELSE IF itemNo = fCurrentSelection THEN
  1204.             fCurrentSelection := 0;
  1205.  
  1206.     fNumberOfItems := fNumberOfItems - 1;
  1207.     AdjustSize;
  1208.  
  1209.     { Invalidate from the deleted item to the end }
  1210.     ItemToVRect(itemNo, topRect);
  1211.     ItemToVRect(fNumberOfItems, bottomRect);
  1212.     topRect.bottom := bottomRect.bottom;
  1213.     InvalidateVRect(topRect);
  1214.     END;
  1215.  
  1216. {--------------------------------------------------------------------------------------------------}
  1217.  
  1218. { Dim highlighting of text by gray XORing is not very readable, so dim highlight a text string
  1219. by framing it with a gray rectangle.  (Standard highlighting when the window displaying
  1220. the view is active is still to invert - black XORing.)    The state transition diagram is:
  1221.  
  1222.                                               hlTo
  1223.  
  1224.                       |     OFF      |           DIM          |       ON
  1225.            -----------|--------------|--------------------|--------------------
  1226.                OFF      |     (NA)     |          Frame       |      Invert
  1227.            -----------|--------------|--------------------|--------------------
  1228. hlFrom           DIM      |     Frame     |          (NA)          |  Frame and Invert
  1229.            -----------|--------------|--------------------|--------------------
  1230.                ON      |    Invert     |    Invert and Frame  |       (NA)
  1231.            -----------|--------------|-----------------------------------------
  1232.  
  1233. Since this matrix is (almost) symmetric, we can add together the hlFrom and hlTo parameters
  1234. and take one action for each of the three possible sums.  }
  1235.  
  1236. PROCEDURE TListView.DoHighlightSelection(fromHL, toHL: HLState); OVERRIDE;
  1237.  
  1238.     VAR
  1239.         itemVRect:            VRect;
  1240.         r:                    Rect;
  1241.  
  1242.     BEGIN
  1243.     IF (fCurrentSelection > 0) THEN
  1244.         BEGIN
  1245.         { Make r be the rectangle to invert }
  1246.         ItemToVRect(fCurrentSelection, itemVRect);
  1247.         ViewToQDRect(itemVRect, r);
  1248.  
  1249.         { Set the pen pattern and mode properly }
  1250.         PenPat(black);
  1251.         PenMode(patXor);
  1252.  
  1253.         IF IsRectDrawable(r) THEN
  1254.             BEGIN
  1255.             CASE (fromHL + toHL) OF
  1256.                 hlOffDim:
  1257.                     BEGIN
  1258.                     UseSelectionColor;
  1259.                     FrameRect(r);
  1260.                     END;
  1261.                 hlOffOn:
  1262.                     BEGIN
  1263.                     UseSelectionColor;
  1264.                     InvertRect(r);
  1265.                     END;
  1266.                 hlDimOn:
  1267.                     IF fromHL = hlDim THEN
  1268.                         BEGIN
  1269.                         UseSelectionColor;
  1270.                         FrameRect(r);
  1271.                         UseSelectionColor;
  1272.                         InvertRect(r);
  1273.                         END
  1274.                     ELSE
  1275.                         BEGIN
  1276.                         UseSelectionColor;
  1277.                         InvertRect(r);
  1278.                         UseSelectionColor;
  1279.                         FrameRect(r);
  1280.                         END;
  1281.             END
  1282.             END
  1283.         END
  1284.     END;
  1285.  
  1286. {--------------------------------------------------------------------------------------------------}
  1287.  
  1288. PROCEDURE TListView.DoMouseCommand(VAR theMouse: VPoint;
  1289.                                    event: TToolboxEvent;
  1290.                                    hysteresis: Point); OVERRIDE;
  1291.  
  1292.     VAR
  1293.         index:                INTEGER;
  1294.  
  1295.     BEGIN
  1296.     index := VPointToItem(theMouse);
  1297.     IF (index > 0) & (index <= fNumberOfItems) THEN
  1298.         ChangeSelection(index, TRUE);
  1299.     END;
  1300.  
  1301. {--------------------------------------------------------------------------------------------------}
  1302.  
  1303. PROCEDURE TListView.Draw(area: VRect); OVERRIDE;
  1304.  
  1305.     VAR
  1306.         i, firstItem, lastItem: INTEGER;
  1307.         viewArea:            VRect;
  1308.         baseVPoint:         VPoint;
  1309.  
  1310.     BEGIN
  1311.     SetPen;
  1312.     viewArea := area;
  1313.     WITH viewArea DO
  1314.         BEGIN
  1315.         {adjust for QuickDraw geometry}
  1316.         bottom := bottom - 1;
  1317.         right := right - 1;
  1318.  
  1319.         firstItem := top DIV fItemHeight + 1;
  1320.         lastItem := Min(fNumberOfItems, bottom DIV fItemHeight + 1);
  1321.         END;
  1322.  
  1323.     SetVPt(baseVPoint, 4, IntMultiply(firstItem - 1, fItemHeight) + fLineAscent);
  1324.     FOR i := firstItem TO lastItem DO
  1325.         BEGIN
  1326.         DrawItem(i, baseVPoint);
  1327.         baseVPoint.v := baseVPoint.v + fItemHeight;
  1328.         END;
  1329.  
  1330.     INHERITED Draw(area);
  1331.     END;
  1332.  
  1333. {--------------------------------------------------------------------------------------------------}
  1334.  
  1335. PROCEDURE TListView.DrawItem(itemNumber: INTEGER;
  1336.                              basePoint: VPoint);
  1337.  
  1338.     BEGIN
  1339.     SubClassResponsibility;
  1340.     END;
  1341.  
  1342. {--------------------------------------------------------------------------------------------------}
  1343.  
  1344. PROCEDURE TListView.Fields(obj: TObject); OVERRIDE;
  1345.  
  1346.     BEGIN
  1347.     WITH obj DO
  1348.         BEGIN
  1349.         DoToField(AtStr('TListView'), NIL, bClass);
  1350.         DoToField(AtStr('fCurrentSelection'), @fCurrentSelection, bInteger);
  1351.         DoToField(AtStr('fNumberOfItems'), @fNumberOfItems, bInteger);
  1352.  
  1353.         DoToField(AtStr('fTextStyle'), @fTextStyle, bTextStyle);
  1354.  
  1355.         DoToField(AtStr('fItemHeight'), @fItemHeight, bInteger);
  1356.         DoToField(AtStr('fLineAscent'), @fLineAscent, bInteger);
  1357.         END;
  1358.     INHERITED Fields(obj);
  1359.     END;
  1360.  
  1361. {--------------------------------------------------------------------------------------------------}
  1362.  
  1363. PROCEDURE TListView.InsertItem(itemNo: INTEGER);
  1364.  
  1365.     VAR
  1366.         topRect, bottomRect: VRect;
  1367.  
  1368.     BEGIN
  1369.     IF (fCurrentSelection > 0) & (itemNo <= fCurrentSelection) THEN
  1370.         fCurrentSelection := fCurrentSelection + 1;
  1371.  
  1372.     fNumberOfItems := fNumberOfItems + 1;
  1373.     AdjustSize;
  1374.  
  1375.     { Invalidate from the inserted item to the end }
  1376.     ItemToVRect(itemNo, topRect);
  1377.     ItemToVRect(fNumberOfItems, bottomRect);
  1378.     topRect.bottom := bottomRect.bottom;
  1379.     InvalidateVRect(topRect);
  1380.     END;
  1381.  
  1382. {--------------------------------------------------------------------------------------------------}
  1383.  
  1384. PROCEDURE TListView.ItemToVRect(index: INTEGER;
  1385.                                 VAR itemRect: VRect);
  1386.  
  1387.     BEGIN
  1388.     GetExtent(itemRect);
  1389.     itemRect.top := IntMultiply(index - 1, fItemHeight); { Subtract 1 to get the TOP line }
  1390.     itemRect.bottom := itemRect.top + fItemHeight;
  1391.     END;
  1392.  
  1393. {--------------------------------------------------------------------------------------------------}
  1394.  
  1395. PROCEDURE TListView.RevealItem(itemNumber: INTEGER);
  1396.  
  1397.     VAR
  1398.         howMuch:            VPoint;
  1399.         rectToReveal:        VRect;
  1400.  
  1401.     BEGIN
  1402.     SetVPt(howMuch, 0, fItemHeight);
  1403.     ItemToVRect(itemNumber, rectToReveal);
  1404.     RevealRect(rectToReveal, howMuch, kRedraw);
  1405.     END;
  1406.  
  1407. {--------------------------------------------------------------------------------------------------}
  1408.  
  1409. PROCEDURE TListView.SelectItem(itemNumber: INTEGER);
  1410.  
  1411.     BEGIN
  1412.     {Can be overridden to do something when an item is selected.}
  1413.     END;
  1414.  
  1415. {--------------------------------------------------------------------------------------------------}
  1416.  
  1417. PROCEDURE TListView.SetNumberOfItems(numberOfItems: INTEGER);
  1418.  
  1419.     BEGIN
  1420.     IF numberOfItems <> fNumberOfItems THEN
  1421.         BEGIN
  1422.         fNumberOfItems := numberOfItems;
  1423.         AdjustSize;
  1424.         END;
  1425.     ForceRedraw;
  1426.     END;
  1427.  
  1428. {--------------------------------------------------------------------------------------------------}
  1429.  
  1430. PROCEDURE TListView.SetStyle(itsTextStyle: TextStyle);
  1431.  
  1432.     VAR
  1433.         aPort:                GrafPort;
  1434.         savedPort:            GrafPtr;
  1435.         theFontInfo:        FontInfo;
  1436.  
  1437.     BEGIN
  1438.     fTextStyle := itsTextStyle;
  1439.  
  1440.     {Need a temporary port to set up the font, so we can get the font info}
  1441.     GetPort(savedPort);
  1442.     OpenPort(@aPort);
  1443.  
  1444.     SetPen;
  1445.     fItemHeight := MAGetFontInfo(theFontInfo);
  1446.     WITH theFontInfo DO
  1447.         fLineAscent := ascent + (leading DIV 2) - 1;
  1448.  
  1449.     SetPort(savedPort);
  1450.     ClosePort(@aPort);
  1451.     AdjustSize;
  1452.     END;                                                { TListView.SetStyle }
  1453.  
  1454. {--------------------------------------------------------------------------------------------------}
  1455.  
  1456. PROCEDURE TListView.SetPen;
  1457.  
  1458.     VAR
  1459.         itsTextStyle:        TextStyle;
  1460.  
  1461.     BEGIN
  1462.     PenNormal;
  1463.     itsTextStyle := fTextStyle;
  1464.     SetPortTextStyle(itsTextStyle);
  1465.     END;
  1466.  
  1467. {--------------------------------------------------------------------------------------------------}
  1468.  
  1469. FUNCTION TListView.VPointToItem(thePoint: VPoint): INTEGER;
  1470.  
  1471.     BEGIN
  1472.     VPointToItem := (thePoint.v DIV fItemHeight) + 1;
  1473.     END;
  1474.  
  1475. {--------------------------------------------------------------------------------------------------}
  1476.  
  1477. PROCEDURE TClassListView.Initialize; OVERRIDE;
  1478.  
  1479.     BEGIN
  1480.     INHERITED Initialize;
  1481.  
  1482.     fInspectWindow := NIL;
  1483.     END;
  1484.  
  1485. {---------------------------------------------------------------------------}
  1486.  
  1487. PROCEDURE TClassListView.IRes(itsDocument: TDocument;
  1488.                               itsSuperView: TView;
  1489.                               VAR itsParams: Ptr); OVERRIDE;
  1490.  
  1491.     VAR
  1492.         aVPt:                VPoint;
  1493.         
  1494.     BEGIN
  1495.     INHERITED IRes(itsDocument, itsSuperView, itsParams);
  1496.  
  1497.     SetVPt(aVPt, 0, fItemHeight);
  1498.     GetScroller(TRUE).SetScrollParameters(aVPt, False, TRUE);
  1499.     END;
  1500.  
  1501. {---------------------------------------------------------------------------}
  1502.  
  1503. PROCEDURE TClassListView.IClassListView(itsWindow: TInspectWindow;
  1504.                                         itsLocation: VPoint;
  1505.                                         itsSize: VPoint);
  1506.  
  1507.     VAR
  1508.         aScroller:            TScroller;
  1509.         aVPt:                VPoint;
  1510.  
  1511.     BEGIN
  1512.     New(aScroller);
  1513.     aScroller.IScroller(itsWindow, itsLocation, itsSize, sizeFixed, sizeFixed, gZeroVPt, False,
  1514.                         TRUE);
  1515.  
  1516.     itsSize.v := 0;                                     { start off with no items }
  1517.     IListView(pInspector, aScroller, gZeroVPt, itsSize, pInspectorStyle, 0, sizeFixed);
  1518.  
  1519.     SetVPt(aVPt, 0, fItemHeight);
  1520.     aScroller.SetScrollParameters(aVPt, False, TRUE);
  1521.  
  1522.     fInspectWindow := itsWindow;
  1523.     END;
  1524.  
  1525. {---------------------------------------------------------------------------}
  1526.  
  1527. PROCEDURE TClassListView.DrawItem(itemNumber: INTEGER;
  1528.                                   basePoint: VPoint); OVERRIDE;
  1529.  
  1530.     VAR
  1531.         className:            MAName;
  1532.         aStringPtr:         StringPtr;
  1533.         p:                    Point;
  1534.  
  1535.     BEGIN
  1536.     GetClassNameFromID(TSortedList(pInspector.fClassesByName.At(itemNumber)).fObjClassId,
  1537.                        className);
  1538.     p := ViewToQDPt(basePoint);
  1539.     MoveTo(p.h, p.v);
  1540.     aStringPtr := StringPtr(@className);
  1541.     DrawString(aStringPtr^);
  1542.     END;
  1543.  
  1544. {---------------------------------------------------------------------------}
  1545.  
  1546. PROCEDURE TClassListView.SelectItem(itemNumber: INTEGER); OVERRIDE;
  1547.  
  1548.     VAR
  1549.         theObjectList:        TSortedList;
  1550.  
  1551.     BEGIN
  1552.     IF itemNumber > 0 THEN
  1553.         BEGIN
  1554.         theObjectList := TSortedList(pInspector.fClassesByName.At(itemNumber));
  1555.         IF (fInspectWindow.fObjListView <> NIL) THEN
  1556.             fInspectWindow.fObjListView.InstallObjectList(theObjectList)
  1557.         ELSE
  1558.             fInspectWindow.fObjListView.ChangeSelection(0, TRUE);
  1559.         END;
  1560.  
  1561.     INHERITED SelectItem(itemNumber);
  1562.     END;
  1563.  
  1564. {---------------------------------------------------------------------------}
  1565.  
  1566. PROCEDURE TClassListView.Fields(obj: TObject); OVERRIDE;
  1567.  
  1568.     BEGIN
  1569.     WITH obj DO
  1570.         BEGIN
  1571.         DoToField(AtStr('TClassListView'), NIL, bClass);
  1572.         DoToField(AtStr('fInspectWindow'), @fInspectWindow, bObject);
  1573.         END;
  1574.     INHERITED Fields(obj);
  1575.     END;
  1576.  
  1577. {--------------------------------------------------------------------------------------------------}
  1578.  
  1579. PROCEDURE TObjListView.Initialize; OVERRIDE;
  1580.  
  1581.     BEGIN
  1582.     INHERITED Initialize;
  1583.  
  1584.     fInspectWindow := NIL;
  1585.     fObjectList := NIL;
  1586.     END;
  1587.  
  1588. {---------------------------------------------------------------------------}
  1589.  
  1590. PROCEDURE TObjListView.IRes(itsDocument: TDocument;
  1591.                             itsSuperView: TView;
  1592.                             VAR itsParams: Ptr); OVERRIDE;
  1593.     VAR
  1594.         aVPt:                VPoint;
  1595.  
  1596.     BEGIN
  1597.     INHERITED IRes(itsDocument, itsSuperView, itsParams);
  1598.  
  1599.     SetVPt(aVPt, 0, fItemHeight);
  1600.     GetScroller(TRUE).SetScrollParameters(aVPt, False, TRUE);
  1601.     END;
  1602.  
  1603. {---------------------------------------------------------------------------}
  1604.  
  1605. PROCEDURE TObjListView.IObjListView(itsWindow: TInspectWindow;
  1606.                                     itsLocation: VPoint;
  1607.                                     itsSize: VPoint);
  1608.  
  1609.     VAR
  1610.         aScroller:            TScroller;
  1611.         aVPt:                VPoint;
  1612.  
  1613.     BEGIN
  1614.     New(aScroller);
  1615.     aScroller.IScroller(itsWindow, itsLocation, itsSize, sizeRelSuperView, sizeFixed, gZeroVPt,
  1616.                         kWantHScrollBar, kWantVScrollBar);
  1617.     itsSize.v := 0;                                     { Start off with no items }
  1618.     IListView(pInspector, aScroller, gZeroVPt, itsSize, pInspectorStyle, 0, sizeRelSuperView);
  1619.     SetVPt(aVPt, 0, fItemHeight);
  1620.     aScroller.SetScrollParameters(aVPt, False, TRUE);
  1621.     fInspectWindow := itsWindow;
  1622.     END;
  1623.  
  1624. {---------------------------------------------------------------------------}
  1625.  
  1626. PROCEDURE TObjListView.DrawItem(itemNumber: INTEGER;
  1627.                                 basePoint: VPoint); OVERRIDE;
  1628.  
  1629.     VAR
  1630.         s1:                 Str255;
  1631.         aString:            Str255;
  1632.         theObject:            TObject;
  1633.         p:                    Point;
  1634.  
  1635.     BEGIN
  1636.     theObject := fObjectList.At(itemNumber);
  1637.     PointerToHex(ORD4(theObject), s1, 6);
  1638.     aString := '';
  1639.     theObject.GetInspectorName(aString);
  1640.     aString := CONCAT(s1, ': ', aString);
  1641.     p := ViewToQDPt(basePoint);
  1642.     MoveTo(p.h, p.v);
  1643.     DrawString(aString);
  1644.     END;
  1645.  
  1646. {---------------------------------------------------------------------------}
  1647.  
  1648. PROCEDURE TObjListView.SelectItem(itemNumber: INTEGER); OVERRIDE;
  1649.  
  1650.     BEGIN
  1651.  {Assume that we've gotten here only if the field is one that can
  1652.   be selected.}
  1653.     IF itemNumber > 0 THEN
  1654.         fInspectWindow.fObjectView.InstallObject(fObjectList.At(itemNumber), bObject);
  1655.  
  1656.     INHERITED SelectItem(itemNumber);
  1657.     END;
  1658.  
  1659. {---------------------------------------------------------------------------}
  1660.  
  1661. PROCEDURE TObjListView.Fields(obj: TObject); OVERRIDE;
  1662.  
  1663.     BEGIN
  1664.     WITH obj DO
  1665.         BEGIN
  1666.         DoToField(AtStr('TObjListView'), NIL, bClass);
  1667.         DoToField(AtStr('fInspectWindow'), @fInspectWindow, bObject);
  1668.         DoToField(AtStr('fObjectList'), @fObjectList, bObject);
  1669.         END;
  1670.     INHERITED Fields(obj);
  1671.     END;
  1672.  
  1673. {---------------------------------------------------------------------------}
  1674.  
  1675. PROCEDURE TObjListView.InstallObjectList(theObjectList: TSortedList);
  1676.  
  1677.     BEGIN
  1678.     ChangeSelection(0, TRUE);
  1679.     IF fObjectList <> theObjectList THEN
  1680.         BEGIN
  1681.         fObjectList := theObjectList;
  1682.         SetNumberOfItems(theObjectList.GetSize);
  1683.         RevealTop(kDontRedraw);
  1684.         ForceRedraw;
  1685.         END;
  1686.     END;
  1687.  
  1688. {---------------------------------------------------------------------------}
  1689.  
  1690. PROCEDURE TObjectView.Initialize; OVERRIDE;
  1691.  
  1692.     BEGIN
  1693.     INHERITED Initialize;
  1694.     fFieldsProc := NIL;
  1695.     fFieldsStaticLink := NIL;
  1696.     fInspectWindow := NIL;
  1697.     fLockState := False;
  1698.     fObject := NIL;
  1699.     fType := bObject;
  1700.     END;
  1701.  
  1702. {---------------------------------------------------------------------------}
  1703.  
  1704. PROCEDURE TObjectView.IRes(itsDocument: TDocument;
  1705.                            itsSuperView: TView;
  1706.                            VAR itsParams: Ptr); OVERRIDE;
  1707.     VAR
  1708.         aVPt:                VPoint;
  1709.         
  1710.  
  1711.     BEGIN
  1712.     INHERITED IRes(itsDocument, itsSuperView, itsParams);
  1713.  
  1714.     SetVPt(aVPt, kSBarSize, fItemHeight);
  1715.     GetScroller(TRUE).SetScrollParameters(aVPt, TRUE, TRUE);
  1716.     END;
  1717.  
  1718. {---------------------------------------------------------------------------}
  1719.  
  1720. PROCEDURE TObjectView.IObjectView(itsWindow: TInspectWindow;
  1721.                                   itsLocation: VPoint;
  1722.                                   itsSize: VPoint);
  1723.  
  1724.     VAR
  1725.         aScroller:            TScroller;
  1726.         aVPt:                VPoint;
  1727.  
  1728.     BEGIN
  1729.     New(aScroller);
  1730.     aScroller.IScroller(itsWindow, itsLocation, itsSize, sizeRelSuperView, sizeRelSuperView, gZeroVPt, TRUE, TRUE);
  1731.     aScroller.fSBarOffsets.bottom := - kSBarSizeMinus1;
  1732.  
  1733.     itsSize.v := 0;                                     { start off with no items }
  1734.     IListView(pInspector, aScroller, gZeroVPt, itsSize, pInspectorStyle, 0, sizeVariable);
  1735.     SetVPt(aVPt, kSBarSize, fItemHeight);
  1736.     aScroller.SetScrollParameters(aVPt, TRUE, TRUE);
  1737.     fInspectWindow := itsWindow;
  1738.     END;
  1739.  
  1740. {---------------------------------------------------------------------------}
  1741.  
  1742. PROCEDURE TObjectView.InspectControlHandle(PROCEDURE
  1743.                                            InspectField(fieldName: StringPtr;
  1744.                                                         fieldAddr: Ptr;
  1745.                                                         fieldType: INTEGER));
  1746.  
  1747.     TYPE
  1748.  {This is an alias for the Control Manager ControlRecord.  The only
  1749.   difference is that this is an unpacked record and contrlVis and
  1750.   contrlHilite are combined in the contrlVisandHilite field.
  1751.   We must have an unpacked record to pass addresses of its fields.}
  1752.         UControlHandle        = ^UControlPtr;
  1753.         UControlPtr         = ^UnpackedControl;
  1754.         UnpackedControl     = RECORD
  1755.             nextControl:        ControlHandle;
  1756.             contrlOwner:        WindowPtr;
  1757.             contrlRect:         Rect;
  1758.             contrlVisandHilite: INTEGER;
  1759.             contrlValue:        INTEGER;
  1760.             contrlMin:            INTEGER;
  1761.             contrlMax:            INTEGER;
  1762.             contrlDefProc:        Handle;
  1763.             contrlData:         Handle;
  1764.             contrlAction:        ProcPtr;
  1765.             contrlrfCon:        LONGINT;
  1766.             contrlTitle:        Str255;
  1767.             END;
  1768.  
  1769.     VAR
  1770.         theControl:     UControlHandle;
  1771.         savedState:     SignedByte;
  1772.  
  1773.     BEGIN
  1774.     theControl := UControlHandle(fObject);
  1775.     savedState := LockHandleHigh(Handle(theControl));
  1776.     WITH theControl^^ DO
  1777.         BEGIN
  1778.         InspectField(AtStr('nextControl'), @nextControl, bControlHandle);
  1779.         InspectField(AtStr('contrlOwner'), @contrlOwner, bWindowPtr);
  1780.         InspectField(AtStr('contrlRect'), @contrlRect, bRect);
  1781.         InspectField(AtStr('contrlVis'), @contrlVisandHilite, bHighByte);
  1782.         InspectField(AtStr('contrlHilite'), @contrlVisandHilite, bLowByte);
  1783.         InspectField(AtStr('contrlValue'), @contrlValue, bInteger);
  1784.         InspectField(AtStr('contrlMin'), @contrlMin, bInteger);
  1785.         InspectField(AtStr('contrlMax'), @contrlMax, bInteger);
  1786.         InspectField(AtStr('contrlDefProc'), @contrlDefProc, bHandle);
  1787.         InspectField(AtStr('contrlData'), @contrlData, bHandle);
  1788.         InspectField(AtStr('contrlrfCon'), @contrlrfCon, bHexLongInt);
  1789.         InspectField(AtStr('contrlTitle'), @contrlTitle, bString);
  1790.         END;
  1791.     HSetState(Handle(theControl), savedState);
  1792.     END;
  1793.  
  1794. {---------------------------------------------------------------------------}
  1795.  
  1796. PROCEDURE TObjectView.InspectGrafPtr(PROCEDURE InspectField(fieldName: StringPtr;
  1797.                                                             fieldAddr: Ptr;
  1798.                                                             fieldType: INTEGER));
  1799.  
  1800.     VAR
  1801.         thePort:            GrafPtr;
  1802.         theCPort:            CGrafPtr;
  1803.  
  1804.     BEGIN
  1805.     thePort := GrafPtr(fObject);
  1806.     theCPort := CGrafPtr(fObject);
  1807.     IF (qNeedsColorQD | gConfiguration.hasColorQD) & (BAND(theCPort^.portVersion, $C000) =
  1808.        $0000C000) THEN                                   { 2 hi bits. IM V pp. 49-50 }
  1809.         WITH theCPort^ DO
  1810.             BEGIN
  1811.             InspectField(AtStr('device'), @device, bInteger);
  1812.             InspectField(AtStr('portPixMap'), @portPixMap, bHandle);
  1813.             InspectField(AtStr('portVersion'), @portVersion, bHexInteger);
  1814.             InspectField(AtStr('grafVars'), @grafVars, bHandle);
  1815.             InspectField(AtStr('chExtra'), @chExtra, bInteger);
  1816.             InspectField(AtStr('pnLocHFrac'), @pnLocHFrac, bHexInteger);
  1817.             InspectField(AtStr('portRect'), @portRect, bRect);
  1818.             InspectField(AtStr('visRgn'), @visRgn, bRgnHandle);
  1819.             InspectField(AtStr('clipRgn'), @clipRgn, bRgnHandle);
  1820.             InspectField(AtStr('bkPixPat'), @bkPixPat, bHandle);
  1821.             InspectField(AtStr('rgbFgColor'), @rgbFgColor, bRGBColor);
  1822.             InspectField(AtStr('rgbBkColor'), @rgbBkColor, bRGBColor);
  1823.             InspectField(AtStr('pnLoc'), @pnLoc, bPoint);
  1824.             InspectField(AtStr('pnSize'), @pnSize, bPoint);
  1825.             InspectField(AtStr('pnMode'), @pnMode, bInteger);
  1826.             InspectField(AtStr('pnPixPat'), @pnPixPat, bHandle);
  1827.             InspectField(AtStr('fillPixPat'), @fillPixPat, bHandle);
  1828.             END
  1829.     ELSE
  1830.         WITH thePort^ DO
  1831.             BEGIN
  1832.             InspectField(AtStr('device'), @device, bInteger);
  1833.             InspectField(AtStr('portBits.baseAddr'), @portBits.baseAddr, bPointer);
  1834.             InspectField(AtStr('portBits.rowBytes'), @portBits.rowBytes, bInteger);
  1835.             InspectField(AtStr('portBits.bounds'), @portBits.bounds, bRect);
  1836.             InspectField(AtStr('portRect'), @portRect, bRect);
  1837.             InspectField(AtStr('visRgn'), @visRgn, bRgnHandle);
  1838.             InspectField(AtStr('clipRgn'), @clipRgn, bRgnHandle);
  1839.             InspectField(AtStr('bkPat'), @bkPat, bPattern);
  1840.             InspectField(AtStr('fillPat'), @fillPat, bPattern);
  1841.             InspectField(AtStr('pnLoc'), @pnLoc, bPoint);
  1842.             InspectField(AtStr('pnSize'), @pnSize, bPoint);
  1843.             InspectField(AtStr('pnMode'), @pnMode, bInteger);
  1844.             InspectField(AtStr('pnPat'), @pnPat, bPattern);
  1845.             END;
  1846.     {The rest of the fields are common to both GrafPorts and CGrafPorts}
  1847.     WITH thePort^ DO
  1848.         BEGIN
  1849.         InspectField(AtStr('pnVis'), @pnVis, bInteger);
  1850.         InspectField(AtStr('txFont'), @txFont, bInteger);
  1851.         InspectField(AtStr('txFace'), @txFace, bHexInteger);
  1852.         InspectField(AtStr('txMode'), @txMode, bInteger);
  1853.         InspectField(AtStr('txSize'), @txSize, bInteger);
  1854.         InspectField(AtStr('spExtra'), @spExtra, bFixed);
  1855.         InspectField(AtStr('fgColor'), @fgColor, bLongInt);
  1856.         InspectField(AtStr('bkColor'), @bkColor, bLongInt);
  1857.         InspectField(AtStr('colrBit'), @colrBit, bInteger);
  1858.         InspectField(AtStr('patStretch'), @patStretch, bInteger);
  1859.         InspectField(AtStr('picSave'), @picSave, bHandle);
  1860.         InspectField(AtStr('rgnSave'), @rgnSave, bHandle);
  1861.         InspectField(AtStr('polySave'), @polySave, bHandle);
  1862.         InspectField(AtStr('grafProcs'), @grafProcs, bPointer);
  1863.         END;
  1864.     END;
  1865.  
  1866. {---------------------------------------------------------------------------}
  1867.  
  1868. PROCEDURE TObjectView.InspectRgnHandle(PROCEDURE InspectField(fieldName: StringPtr;
  1869.                                                               fieldAddr: Ptr;
  1870.                                                               fieldType: INTEGER));
  1871.  
  1872.     VAR
  1873.         theRgn:         RgnHandle;
  1874.         savedState:     SignedByte;
  1875.  
  1876.     BEGIN
  1877.     theRgn := RgnHandle(fObject);
  1878.     savedState := LockHandleHigh(Handle(theRgn));
  1879.     WITH theRgn^^ DO
  1880.         BEGIN
  1881.         InspectField(AtStr('rgnSize'), @rgnSize, bInteger);
  1882.         InspectField(AtStr('rgnBBox'), @rgnBBox, bRect);
  1883.         END;
  1884.     HSetState(Handle(theRgn), savedState);
  1885.     END;
  1886.  
  1887. {---------------------------------------------------------------------------}
  1888.  
  1889. PROCEDURE TObjectView.InspectHandle(PROCEDURE InspectField(fieldName: StringPtr;
  1890.                                                            fieldAddr: Ptr;
  1891.                                                            fieldType: INTEGER));
  1892.  
  1893.     VAR
  1894.         theHandle:            Handle;
  1895.  
  1896.     PROCEDURE ShowMemory(startAddress, numBytes: LONGINT);
  1897.  
  1898.         VAR
  1899.             i:                    INTEGER;
  1900.             addr, lineAddr:     LONGINT;
  1901.             numeric:            STRING[40];
  1902.             ascii:                STRING[16];
  1903.             numPos:             INTEGER;
  1904.             ascPos:             INTEGER;
  1905.             decNumber:            LONGINT;
  1906.             chCode:             INTEGER;
  1907.             j:                    INTEGER;
  1908.  
  1909. {--------------------------------------------------------------------------------------------------}
  1910.  
  1911.         PROCEDURE BlankLine;
  1912.  
  1913.             CONST
  1914.                 k8Spaces            = '        ';
  1915.  
  1916.             BEGIN
  1917.             ascii := CONCAT(k8Spaces, k8Spaces);
  1918.             numeric := CONCAT(ascii, ascii, k8Spaces);
  1919.             numPos := 0;
  1920.             ascPos := 0;
  1921.             END;
  1922.  
  1923. {--------------------------------------------------------------------------------------------------}
  1924.  
  1925.         PROCEDURE PrintLine;
  1926.  
  1927.             VAR
  1928.                 aStr:                Str255;
  1929.                 tempString:         String8;
  1930.  
  1931.             BEGIN
  1932.             LIntToHex(lineAddr, tempString, 8);
  1933.             aStr := CONCAT('$', tempString, ': ', numeric, '  ', ascii);
  1934.             InspectField(AtStr(''), @aStr, bInternalString);
  1935.  
  1936.             END;
  1937.  
  1938.         BEGIN
  1939.         IF ODD(startAddress) THEN
  1940.             InspectField(AtStr('Odd Address'), NIL, bTitle)
  1941.         ELSE IF numBytes > 0 THEN
  1942.             BEGIN
  1943.             BlankLine;
  1944.  
  1945.             FOR i := 0 TO (numBytes - 1) DIV 2 DO
  1946.                 BEGIN
  1947.                 addr := startAddress + i + i;
  1948.  
  1949.                 IF (i MOD 8) = 0 THEN
  1950.                     BEGIN
  1951.                     IF i > 0 THEN
  1952.                         BEGIN
  1953.                         PrintLine;
  1954.                         BlankLine;
  1955.                         END;
  1956.                     lineAddr := addr;                    { save the address for printline to use }
  1957.                     END;
  1958.  
  1959.                 decNumber := IntegerPtr(addr)^;
  1960.                 FOR j := 4 DOWNTO 1 DO
  1961.                     BEGIN
  1962.                     numeric[numPos + j] := kHexDigits[BAND(decNumber, 15) + 1];
  1963.                     decNumber := BSR(decNumber, 4);
  1964.                     END;
  1965.  
  1966.                 decNumber := IntegerPtr(addr)^;
  1967.                 FOR j := 2 DOWNTO 1 DO
  1968.                     BEGIN
  1969.                     chCode := BAND(decNumber, 255);
  1970.                     IF (chCode < $20) | (chCode > $D8) | (chCode = $7F) THEN { control, unassigned,
  1971.                            or DEL }
  1972.                         chCode := ord('•');
  1973.                     ascii[ascPos + j] := CHR(chCode);
  1974.                     decNumber := BSR(decNumber, 8);
  1975.                     END;
  1976.  
  1977.                 numPos := numPos + 5;
  1978.                 ascPos := ascPos + 2;
  1979.                 END;
  1980.  
  1981.             PrintLine;
  1982.             END;
  1983.         END;
  1984.  
  1985.     BEGIN
  1986.     theHandle := Handle(fObject);
  1987.     ShowMemory(longint(theHandle^), GetHandleSize(theHandle));
  1988.     END;
  1989.  
  1990. {---------------------------------------------------------------------------}
  1991.  
  1992. PROCEDURE TObjectView.InspectTEHandle(PROCEDURE InspectField(fieldName: StringPtr;
  1993.                                                              fieldAddr: Ptr;
  1994.                                                              fieldType: INTEGER));
  1995.  
  1996.     VAR
  1997.         hTE:            TEHandle;
  1998.         savedState:     SignedByte;
  1999.  
  2000.     BEGIN
  2001.     hTE := TEHandle(fObject);
  2002.     savedState := LockHandleHigh(Handle(hTE));
  2003.     WITH hTE^^ DO
  2004.         BEGIN
  2005.         InspectField(AtStr('destRect'), @destRect, bRect);
  2006.         InspectField(AtStr('viewRect'), @viewRect, bRect);
  2007.         InspectField(AtStr('selRect'), @selRect, bRect);
  2008.         InspectField(AtStr('lineHeight'), @lineHeight, bInteger);
  2009.         InspectField(AtStr('fontAscent'), @fontAscent, bInteger);
  2010.         InspectField(AtStr('selPoint'), @selPoint, bPoint);
  2011.         InspectField(AtStr('selStart'), @selStart, bInteger);
  2012.         InspectField(AtStr('selEnd'), @selEnd, bInteger);
  2013.         InspectField(AtStr('active'), @active, bInteger);
  2014.         InspectField(AtStr('wordBreak'), @wordBreak, bPointer);
  2015.         InspectField(AtStr('clikLoop'), @clikLoop, bPointer);
  2016.         InspectField(AtStr('clickTime'), @clickTime, bLongInt);
  2017.         InspectField(AtStr('clickLoc'), @clickLoc, bInteger);
  2018.         InspectField(AtStr('caretTime'), @caretTime, bLongInt);
  2019.         InspectField(AtStr('caretState'), @caretState, bInteger);
  2020.         InspectField(AtStr('just'), @just, bInteger);
  2021.         InspectField(AtStr('teLength'), @teLength, bInteger);
  2022.         InspectField(AtStr('hText'), @hText, bHandle);
  2023.         InspectField(AtStr('recalBack'), @recalBack, bInteger);
  2024.         InspectField(AtStr('recalLines'), @recalLines, bInteger);
  2025.         InspectField(AtStr('clikStuff'), @clikStuff, bHexInteger);
  2026.         InspectField(AtStr('crOnly'), @crOnly, bInteger);
  2027.   {If txSize is -1 then the txFont and txFace fields are replaced
  2028.    by a handle to a style record.  See Inside Mac Vol. 5.}
  2029.         IF txSize = - 1 THEN
  2030.             InspectField(AtStr('txFont,txFace'), @txFont, bHandle)
  2031.         ELSE
  2032.             BEGIN
  2033.             InspectField(AtStr('txFont'), @txFont, bInteger);
  2034.             InspectField(AtStr('txFace'), @txFace, bStyle);
  2035.             END;
  2036.         InspectField(AtStr('txMode'), @txMode, bInteger);
  2037.         InspectField(AtStr('txSize'), @txSize, bInteger);
  2038.         InspectField(AtStr('inPort'), @inPort, bGrafPtr);
  2039.         InspectField(AtStr('highHook'), @highHook, bPointer);
  2040.         InspectField(AtStr('caretHook'), @caretHook, bPointer);
  2041.         InspectField(AtStr('nLines'), @nLines, bInteger);
  2042.         END;
  2043.     HSetState(Handle(hTE), savedState);
  2044.     END;
  2045.  
  2046. {---------------------------------------------------------------------------}
  2047.  
  2048. PROCEDURE TObjectView.InspectWindowPtr(PROCEDURE InspectField(fieldName: StringPtr;
  2049.                                                               fieldAddr: Ptr;
  2050.                                                               fieldType: INTEGER));
  2051.  
  2052.     VAR
  2053.         theWindow:            WindowPeek;
  2054.  
  2055.     BEGIN
  2056.     InspectGrafPtr(InspectField);
  2057.     theWindow := WindowPeek(fObject);
  2058.     WITH theWindow^ DO
  2059.         BEGIN
  2060.         InspectField(AtStr('windowKind'), @windowKind, bInteger);
  2061.         InspectField(AtStr('visible'), @visible, bBoolean);
  2062.         InspectField(AtStr('hilited'), @hilited, bBoolean);
  2063.         InspectField(AtStr('goAwayFlag'), @goAwayFlag, bBoolean);
  2064.         InspectField(AtStr('spareFlag'), @spareFlag, bBoolean);
  2065.         InspectField(AtStr('strucRgn'), @strucRgn, bRgnHandle);
  2066.         InspectField(AtStr('contRgn'), @contRgn, bRgnHandle);
  2067.         InspectField(AtStr('updateRgn'), @updateRgn, bRgnHandle);
  2068.         InspectField(AtStr('windowDefProc'), @windowDefProc, bHandle);
  2069.         InspectField(AtStr('dataHandle'), @dataHandle, bHandle);
  2070.         InspectField(AtStr('titleHandle'), @titleHandle, bHandle);
  2071.         InspectField(AtStr('titleWidth'), @titleWidth, bInteger);
  2072.         InspectField(AtStr('controlList'), @controlList, bControlHandle);
  2073.         InspectField(AtStr('nextWindow'), @nextWindow, bWindowPtr);
  2074.         InspectField(AtStr('windowPic'), @windowPic, bHandle);
  2075.         InspectField(AtStr('refCon'), @refCon, bHexLongInt);
  2076.         END;
  2077.     END;
  2078.  
  2079. {---------------------------------------------------------------------------}
  2080.  
  2081. PROCEDURE TObjectView.ChangeSelection(index: INTEGER;
  2082.                                       highlight: BOOLEAN); OVERRIDE;
  2083.  
  2084.     BEGIN
  2085.     SelectField(index, fInspectWindow);
  2086.     END;
  2087.  
  2088. {---------------------------------------------------------------------------}
  2089.  
  2090. PROCEDURE TObjectView.SelectField(index: INTEGER;
  2091.                                   inspectWindow: TInspectWindow);
  2092.  
  2093.     VAR
  2094.         fieldNo:            INTEGER;
  2095.  
  2096.     FUNCTION TestField(fieldName: StringPtr;
  2097.                        fieldAddr: Ptr;
  2098.                        fieldType: INTEGER): BOOLEAN;
  2099.  
  2100.         VAR
  2101.             count:                INTEGER;
  2102.  
  2103.         PROCEDURE TestSubField(theLabel: StringPtr;
  2104.                                theString: StringPtr;
  2105.                                theData: Ptr;
  2106.                                theType: INTEGER);
  2107.  
  2108.             BEGIN
  2109.             IF fieldNo = index THEN
  2110.                 BEGIN
  2111.                 CASE theType OF
  2112.                     bObject:
  2113.                         IF IsObject(TObjectPtrPtr(theData)^) THEN
  2114.                             inspectWindow.SelectObject(TObjectPtrPtr(theData)^, theType);
  2115.                     bGrafPtr, bWindowPtr, bTEHandle, bControlHandle, bRgnHandle, bHandle:
  2116.                         BEGIN
  2117.                         IF Handle(theData)^ <> NIL THEN
  2118.                             inspectWindow.SelectObject(TObjectPtrPtr(theData)^, theType);
  2119.                         END;
  2120.                 END;
  2121.                 END;
  2122.             fieldNo := fieldNo + 1;                     { increment so we don't test fieldNo again }
  2123.             END;
  2124.  
  2125.         BEGIN
  2126.         count := 0;
  2127.         FieldToCount(count, fieldType);
  2128.         IF fieldNo = index THEN
  2129.             BEGIN
  2130.             CASE fieldType OF
  2131.                 bObject:
  2132.                     IF IsObject(TObjectPtrPtr(fieldAddr)^) THEN
  2133.                         inspectWindow.SelectObject(TObjectPtrPtr(fieldAddr)^, fieldType);
  2134.                 bGrafPtr, bWindowPtr, bTEHandle, bControlHandle, bRgnHandle, bHandle:
  2135.                     BEGIN
  2136.                     IF Handle(fieldAddr)^ <> NIL THEN
  2137.                         inspectWindow.SelectObject(TObjectPtrPtr(fieldAddr)^, fieldType);
  2138.                     END;
  2139.             END;
  2140.             TestField := TRUE;
  2141.             END
  2142.         ELSE IF (fieldNo + count) >= index THEN         { Have we chosen subfield of compound type?
  2143.                                                          }
  2144.             BEGIN
  2145.             FieldToString(fieldName, fieldAddr, fieldType, TestSubField);
  2146.             TestField := TRUE;
  2147.             END
  2148.         ELSE
  2149.             BEGIN
  2150.             TestField := False;
  2151.             fieldNo := fieldNo + count + 1;
  2152.             END;
  2153.         END;
  2154.  
  2155.     BEGIN
  2156.     IF (index > 0) & (index <= fNumberOfItems) THEN
  2157.         BEGIN
  2158.         fieldNo := 2;                                    { Skip title line }
  2159.         LockObject;
  2160.         FirstFieldThat(TestField);
  2161.         UnlockObject;
  2162.         END;
  2163.     END;
  2164.  
  2165. {--------------------------------------------------------------------------------------------------}
  2166.  
  2167. PROCEDURE TObjectView.DoMouseCommand(VAR theMouse: VPoint;
  2168.                                      event: TToolboxEvent;
  2169.                                      hysteresis: Point); OVERRIDE;
  2170.  
  2171.     VAR
  2172.         index:                INTEGER;
  2173.         newInspectWindow:    TInspectWindow;
  2174.         wasAddNewObjectsToInspector: BOOLEAN;
  2175.  
  2176.     BEGIN
  2177.     IF event.fOptionKey THEN
  2178.         BEGIN
  2179.         index := VPointToItem(theMouse);
  2180.         IF (index > 0) & (index <= fNumberOfItems) THEN
  2181.             BEGIN
  2182. {$IFC NOT qDebugTheDebugger}
  2183.             wasAddNewObjectsToInspector := AddNewObjectsToInspector(False);
  2184. {$ENDC}
  2185.             newInspectWindow := pInspector.MakeWindow;
  2186. {$IFC NOT qDebugTheDebugger}
  2187.             wasAddNewObjectsToInspector := AddNewObjectsToInspector(wasAddNewObjectsToInspector);
  2188. {$ENDC}
  2189.  
  2190.             SelectField(index, newInspectWindow);
  2191.             newInspectWindow.Open;
  2192.             END;
  2193.         END
  2194.     ELSE
  2195.         INHERITED DoMouseCommand(theMouse, event, hysteresis);
  2196.     END;
  2197.  
  2198. {--------------------------------------------------------------------------------------------------}
  2199.  
  2200. PROCEDURE TObjectView.Draw(area: VRect); OVERRIDE;
  2201.  
  2202.     VAR
  2203.         fieldNo, firstField, lastField: INTEGER;
  2204.         viewArea:            VRect;
  2205.         baseVPoint:         VPoint;
  2206.         basePoint:            Point;
  2207.         aString:            Str255;
  2208.  
  2209.     PROCEDURE FitString(VAR theString: Str255;
  2210.                         maxWidth: INTEGER);
  2211.     { Truncates theString to fit in maxWidth pixels }
  2212.  
  2213.         VAR
  2214.             currWidth:            INTEGER;
  2215.             noOfChars:            INTEGER;
  2216.  
  2217.         BEGIN
  2218.         IF StringWidth(theString) > maxWidth THEN
  2219.             BEGIN
  2220.             currWidth := CharWidth('…');
  2221.             noOfChars := 0;
  2222.             REPEAT
  2223.                 noOfChars := noOfChars + 1;
  2224.                 currWidth := currWidth + CharWidth(theString[noOfChars]);
  2225.             UNTIL currWidth > maxWidth;
  2226.  
  2227. {$Push} {$R-}
  2228.             theString[0] := CHR(noOfChars);             { Set length of theString }
  2229. {$Pop}
  2230.             theString[noOfChars] := '…';
  2231.             END;
  2232.         END;
  2233.  
  2234.     PROCEDURE GetTitle(VAR aString: Str255);
  2235.  
  2236.         VAR
  2237.             typeName:            Str255;
  2238.             aStringPtr:         MANamePtr;
  2239.  
  2240.         BEGIN
  2241.         CASE fType OF
  2242.             bObject:
  2243.                 BEGIN
  2244.                 aStringPtr := MANamePtr(@typeName);
  2245.                 fObject.GetClassName(aStringPtr^);
  2246.                 END;
  2247.             bGrafPtr:
  2248.                 typeName := 'GrafPtr:';
  2249.             bWindowPtr:
  2250.                 typeName := 'WindowPtr:';
  2251.             bControlHandle:
  2252.                 typeName := 'ControlHandle:';
  2253.             bRgnHandle:
  2254.                 typeName := 'RgnHandle:';
  2255.             bTEHandle:
  2256.                 typeName := 'TEHandle:';
  2257.             bHandle:
  2258.                 typeName := 'Handle:';
  2259.         END;
  2260.         PointerToHex(ORD4(fObject), aString, 6);
  2261.         aString := CONCAT(typeName, '  ', aString);
  2262.         IF fType = bObject THEN
  2263.             BEGIN
  2264.             typeName := '';
  2265.             fObject.GetInspectorName(typeName);
  2266.             aString := CONCAT(aString, '  ', typeName);
  2267.             END;
  2268.         END;
  2269.  
  2270.     FUNCTION DrawField(fieldName: StringPtr;
  2271.                        fieldAddr: Ptr;
  2272.                        fieldType: INTEGER): BOOLEAN;
  2273.  
  2274.         VAR
  2275.             count:                INTEGER;
  2276.  
  2277.         PROCEDURE OutputType(theLabel: StringPtr;
  2278.                              theString: StringPtr;
  2279.                              theData: Ptr;
  2280.                              theType: INTEGER);
  2281.  
  2282.             VAR
  2283.                 s1:                 Str255;
  2284.                 aString:            Str255;
  2285.                 aStringPtr:         MANamePtr;
  2286.                 theObject:            TObject;
  2287.  
  2288.             BEGIN
  2289.             IF (fieldNo >= firstField) & (fieldNo <= lastField) THEN
  2290.                 BEGIN
  2291.                 IF theLabel <> NIL THEN
  2292.                     BEGIN
  2293.                     aString := CONCAT('   ', theLabel^, ': ');
  2294.                     FitString(aString, Max(94, BSR(fSuperView.fSize.h, 1)));
  2295.                     MoveTo(4, basePoint.v);
  2296.                     DrawString(aString);
  2297.                     TextFace([]);
  2298.                     END;
  2299.  
  2300.                 CASE theType OF
  2301.                     bObject, bGrafPtr, bWindowPtr, bControlHandle, bRgnHandle, bTEHandle, bHandle:
  2302.                         IF Handle(theData)^ <> NIL THEN
  2303.                             TextFace([bold]);
  2304.                     OTHERWISE;
  2305.                 END;
  2306.  
  2307.                 MoveTo(Max(100, BSR(fSuperView.fSize.h, 1) + 4), basePoint.v);
  2308.  
  2309.                 IF (theType = bObject) & IsObject(TObjectPtrPtr(theData)^) THEN
  2310.                     BEGIN
  2311.                     theObject := TObjectPtrPtr(theData)^;
  2312.                     { $xxxxx: ClassName Inspectorname }
  2313.                     PointerToHex(ORD4(theObject), aString, 6);
  2314.  
  2315.                     aStringPtr := MANamePtr(@s1);
  2316.                     theObject.GetClassName(aStringPtr^);
  2317.                     aString := CONCAT(aString, ': ', s1);
  2318.  
  2319.                     s1 := '';
  2320.                     theObject.GetInspectorName(s1);
  2321.                     aString := CONCAT(aString, ' ', s1);
  2322.                     DrawString(aString);
  2323.                     END
  2324.                 ELSE
  2325.                     DrawString(theString^);
  2326.  
  2327.                 TextFace([]);
  2328.                 basePoint.v := basePoint.v + fItemHeight;
  2329.                 END;
  2330.             fieldNo := fieldNo + 1;
  2331.             END;
  2332.  
  2333.         BEGIN
  2334.         DrawField := False;
  2335.         count := 0;
  2336.         FieldToCount(count, fieldType);
  2337.         IF (fieldNo + count) >= firstField THEN
  2338.             BEGIN
  2339.             IF fieldNo > lastField THEN
  2340.                 BEGIN
  2341.                 DrawField := TRUE;
  2342.                 END
  2343.             ELSE
  2344.                 BEGIN
  2345.                 IF fieldType = bInternalString THEN
  2346.                     BEGIN
  2347.                     MoveTo(4, basePoint.v);
  2348.                     DrawString(StringPtr(fieldAddr)^);
  2349.                     TextFace([]);
  2350.                     basePoint.v := basePoint.v + fItemHeight;
  2351.                     fieldNo := fieldNo + 1;
  2352.                     END
  2353.                 ELSE
  2354.                     BEGIN
  2355.                     IF fieldType = bClass THEN
  2356.                         BEGIN
  2357.                         aString := fieldName^;
  2358.                         TextFace([underline]);
  2359.                         MoveTo(4, basePoint.v);
  2360.                         DrawString(aString);
  2361.                         TextFace([]);
  2362.                         basePoint.v := basePoint.v + fItemHeight;
  2363.                         fieldNo := fieldNo + 1;
  2364.                         END
  2365.                     ELSE
  2366.                         FieldToString(fieldName, fieldAddr, fieldType, OutputType);
  2367.                     END;
  2368.                 END;
  2369.             END
  2370.         ELSE
  2371.             fieldNo := fieldNo + count + 1;
  2372.         END;
  2373.  
  2374.     BEGIN
  2375.     IF fObject <> NIL THEN
  2376.         BEGIN
  2377.         SetPen;
  2378.         viewArea := area;
  2379.         WITH viewArea DO
  2380.             BEGIN
  2381.             {adjust for QuickDraw geometry}
  2382.             bottom := bottom - 1;
  2383.             right := right - 1;
  2384.  
  2385.             firstField := top DIV fItemHeight + 1;
  2386.             lastField := Min(fNumberOfItems, bottom DIV fItemHeight + 1);
  2387.             END;
  2388.  
  2389.         SetVPt(baseVPoint, 4, IntMultiply(firstField - 1, fItemHeight) + fLineAscent);
  2390.         basePoint := ViewToQDPt(baseVPoint);
  2391.  
  2392.         IF firstField = 1 THEN
  2393.             BEGIN
  2394.             GetTitle(aString);
  2395.             MoveTo(basePoint.h, basePoint.v);
  2396.             DrawString(aString);
  2397.             basePoint.v := basePoint.v + fItemHeight;
  2398.             END;
  2399.  
  2400.         fieldNo := 2;                                    { Skip title line }
  2401.         LockObject;
  2402.         FirstFieldThat(DrawField);
  2403.         UnlockObject;
  2404.         END;
  2405.  
  2406.     INHERITED Draw(area);
  2407.     END;
  2408.  
  2409. {---------------------------------------------------------------------------}
  2410.  
  2411. PROCEDURE TObjectView.DrawItem(itemNumber: INTEGER;
  2412.                                basePoint: VPoint); OVERRIDE;
  2413.  
  2414.     BEGIN
  2415.     { Do nothing - we've already imaged our list. Don't call INHERITED DrawItem because
  2416.     you'll get a "SubClassResponsibility" notification. }
  2417.     END;
  2418.  
  2419. {---------------------------------------------------------------------------}
  2420.  
  2421. PROCEDURE TObjectView.SuperViewChangedSize(delta: VPoint;
  2422.                                            invalidate: BOOLEAN);
  2423.  
  2424.     BEGIN
  2425.     IF invalidate THEN
  2426.         ForceRedraw;
  2427.     INHERITED SuperViewChangedSize(delta, invalidate);
  2428.     END;
  2429.  
  2430. {---------------------------------------------------------------------------}
  2431.  
  2432. PROCEDURE TObjectView.Resize(newSize: VPoint;
  2433.                              invalidate: BOOLEAN); OVERRIDE;
  2434.  
  2435.     BEGIN
  2436.     {$Push}{$H-}
  2437.     IF invalidate & NOT EqualVPt(fSize, newSize) THEN
  2438.         ForceRedraw;
  2439.     {$Pop}
  2440.     INHERITED Resize(newSize, invalidate);
  2441.     END;
  2442.  
  2443. {---------------------------------------------------------------------------}
  2444.  
  2445. PROCEDURE TObjectView.FirstFieldThat(FUNCTION TestField(fieldName: StringPtr;
  2446.                                                         fieldAddr: Ptr;
  2447.                                                         fieldType: INTEGER): BOOLEAN);
  2448.  
  2449.     LABEL 1000;
  2450.  
  2451.     VAR
  2452.         oldState:            BOOLEAN;
  2453.         fi:                 FailInfo;
  2454.  
  2455.     PROCEDURE HandleFailure(error: INTEGER;
  2456.                             message: LONGINT);
  2457.  
  2458.         BEGIN
  2459.         IF error = 0 THEN
  2460.             GOTO 1000
  2461.         ELSE                                            { someone else signalled it, just let it
  2462.                                                          propagate. }
  2463.             BEGIN
  2464. {$IFC qDebug}
  2465.             gIntenseDebugging := oldState;
  2466. {$EndC}
  2467.             END;
  2468.         END;
  2469.  
  2470.     PROCEDURE TestAField(fieldName: StringPtr;
  2471.                          fieldAddr: Ptr;
  2472.                          fieldType: INTEGER);
  2473.  
  2474.         BEGIN
  2475.         IF TestField(fieldName, fieldAddr, fieldType) THEN
  2476.             Failure(0, 0);                                { this is kinder to .Fields methods that
  2477.                                                          would quiver when a simple exit would yank
  2478.                                                          the rug out from under them }
  2479.         END;
  2480.  
  2481.     BEGIN
  2482. {$IFC qDebug}
  2483.     oldState := gIntenseDebugging;
  2484.     gIntenseDebugging := False;                         { Suppress printing of info from failure
  2485.                                                          signals }
  2486. {$EndC}
  2487.  
  2488.     CatchFailures(fi, HandleFailure);
  2489.     CASE fType OF
  2490.         bObject:
  2491.             BEGIN
  2492.             { Setup the pointer and Staticlink for the nested call back.
  2493.             My DoToField method will be called and it will call back through them. }
  2494.             fFieldsProc := @TestAField;
  2495.             fFieldsStaticLink := GetCurStackFramePtr;
  2496.  
  2497.             fObject.Fields(SELF);
  2498.             END;
  2499.         bGrafPtr:
  2500.             InspectGrafPtr(TestAField);
  2501.         bWindowPtr:
  2502.             InspectWindowPtr(TestAField);
  2503.         bControlHandle:
  2504.             InspectControlHandle(TestAField);
  2505.         bRgnHandle:
  2506.             InspectRgnHandle(TestAField);
  2507.         bTEHandle:
  2508.             InspectTEHandle(TestAField);
  2509.         bHandle:
  2510.             InspectHandle(TestAField);
  2511.     END;
  2512.     Success(fi);
  2513.  
  2514. 1000:
  2515. {$IFC qDebug}
  2516.     gIntenseDebugging := oldState;
  2517. {$EndC}
  2518.  
  2519.     END;
  2520.  
  2521. {---------------------------------------------------------------------------}
  2522.  
  2523. PROCEDURE TObjectView.Fields(obj: TObject); OVERRIDE;
  2524.  
  2525.     BEGIN
  2526.     WITH obj DO
  2527.         BEGIN
  2528.         DoToField(AtStr('TObjectView'), NIL, bClass);
  2529.         DoToField(AtStr('fInspectWindow'), @fInspectWindow, bObject);
  2530.         DoToField(AtStr('fObject'), @fObject, bObject);
  2531.         DoToField(AtStr('fType'), @fType, bInteger);
  2532.         DoToField(AtStr('fLockState'), @fLockState, bBoolean);
  2533.  
  2534.         END;
  2535.     INHERITED Fields(obj);
  2536.     END;
  2537.  
  2538. {---------------------------------------------------------------------------}
  2539.  
  2540. PROCEDURE CallFieldsProc(fieldName: StringPtr;
  2541.                          fieldAddr: Ptr;
  2542.                          fieldType: INTEGER;
  2543.                          fieldsStaticLink: Ptr;
  2544.                          fieldsProc: ProcPtr);
  2545.     INLINE $205F, $4E90;
  2546. {  MOVE.L  (A7)+,A0
  2547. JSR (A0)
  2548. }
  2549.  
  2550. PROCEDURE TObjectView.DoToField(fieldName: StringPtr;
  2551.                                 fieldAddr: Ptr;
  2552.                                 fieldType: INTEGER); OVERRIDE;
  2553.  
  2554.     BEGIN
  2555.     CallFieldsProc(fieldName, fieldAddr, fieldType, fFieldsStaticLink, fFieldsProc);
  2556.     END;
  2557.  
  2558. {---------------------------------------------------------------------------}
  2559.  
  2560. PROCEDURE TObjectView.InstallObject(theObject: TObject;
  2561.                                     theObjectType: INTEGER);
  2562.  
  2563.     VAR
  2564.         noOfFields:         INTEGER;
  2565.  
  2566.     FUNCTION CountField(fieldName: StringPtr;
  2567.                         fieldAddr: Ptr;
  2568.                         fieldType: INTEGER): BOOLEAN;
  2569.  
  2570.         BEGIN
  2571.         CountField := False;
  2572.         noOfFields := noOfFields + 1;                    { Include 1 line for title }
  2573.         FieldToCount(noOfFields, fieldType);            { Add additional fields for compound types }
  2574.         END;
  2575.  
  2576.     BEGIN
  2577.     fObject := theObject;
  2578.     fType := theObjectType;
  2579.     noOfFields := 1;                                    { Includes 1 line for title }
  2580.     IF theObject <> NIL THEN
  2581.         BEGIN
  2582.         LockObject;
  2583.         FirstFieldThat(CountField);
  2584.         UnlockObject;
  2585.         END;
  2586.     SetNumberOfItems(noOfFields);
  2587.     RevealTop(kDontRedraw);
  2588.     END;
  2589.  
  2590. {---------------------------------------------------------------------------}
  2591.  
  2592. PROCEDURE TObjectView.LockObject;
  2593.  
  2594.     BEGIN
  2595.     IF fType = bObject THEN
  2596.         fLockState := fObject.Lock(TRUE)
  2597.     ELSE IF (fType = bHandle) | (fType = bTEHandle) | (fType = bControlHandle) | (fType =
  2598.             bRgnHandle) THEN
  2599.         BEGIN
  2600.         fLockState := IsHandleLocked(fObject);
  2601.         IF NOT fLockState THEN
  2602.             HLock(Handle(fObject));
  2603.         END;
  2604.     END;
  2605.  
  2606. {---------------------------------------------------------------------------}
  2607.  
  2608. PROCEDURE TObjectView.UnlockObject;
  2609.  
  2610.     VAR
  2611.         oldState:            BOOLEAN;
  2612.  
  2613.     BEGIN
  2614.     IF fType = bObject THEN
  2615.         oldState := fObject.Lock(fLockState)
  2616.     ELSE IF (fType = bHandle) | (fType = bTEHandle) | (fType = bControlHandle) | (fType =
  2617.             bRgnHandle) THEN
  2618.         IF NOT fLockState THEN
  2619.             HUnLock(Handle(fObject));
  2620.     END;
  2621.